Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive...

97
Finding and Fixing Bugs in Liquid Haskell Anish Tondwalkar

Transcript of Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive...

Page 1: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Finding and Fixing Bugs in Liquid Haskell

Anish Tondwalkar

Page 2: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Overview

● Motivation● Liquid Haskell● Fault Localization● Fault Localization Evaluation● Predicate Discovery● Predicate Discovery Evaluation● Conclusion

Page 3: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Motivation:Bugs are Bad

Page 4: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Bugs are Bad

● Bugs are Expensive○ Modifying code, correcting defects, and evolving code account for as

much as 90% of the total cost of software projects.

Page 5: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Bugs are Bad

● Bugs are Expensive● Bugs are Dangerous

Page 6: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Programming Languages to the Rescue!

George Orwell (1984)

Page 7: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Presence of bugs...is half the problem

Page 8: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Verification, Model Checking, and Type Systems

We can check the correctness of programs against formal specifications, which is information we can encode in Liquid Haskell type signatures.

● We still have to find the bug after we know it exists● What about missing parts of the specification?

Page 9: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Contributions

● We still have to find the bug after we know it exists

Our fault localization algorithm searches for a minimal unsatisfiable constraint set, whose constraints map to likely locations of the bug in the implementation.

● What about missing parts of the specification?

Our predicate discovery algorithm uses disjunctive interpolation to automatically expand the abstract domain by inferring predicate templates that serve as the refinement types of program expressions.

Page 10: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Contributions

● We still have to find the bug after we know it exists

A fault localization algorithm searches for a minimal unsatisfiable constraint set, whose constraints map to likely locations of the bug in the implementation.

● What about missing parts of the specification?

Our predicate discovery algorithm uses disjunctive interpolation to automatically expand the abstract domain by inferring predicate templates that serve as the refinement types of program expressions.

Page 11: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Contributions

● We still have to find the bug after we know it exists

A fault localization algorithm searches for a minimal unsatisfiable constraint set, whose constraints map to likely locations of the bug in the implementation.

● What about missing parts of the specification?

A predicate discovery algorithm uses disjunctive interpolation to automatically expand the abstract domain by inferring predicate templates that serve as the refinement types of program expressions.

Page 12: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Liquid Haskell

Page 13: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Well-typed (Haskell) programs can go very wrong!

Divide-by-zero

Keys missing in Maps

Pattern-match failures

Non-termination

Functional Correctness / Assertions...

Page 14: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Solution:Refinement Types

Page 15: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Simple Refinement Types

Refinement Types = Types + Predicates

Page 16: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Refinement Types

Types

b := Int | Bool | ... -- primitives

| a, b, c -- variables

Refinements

t := {x:b | p} -- refined base

| x:t -> t -- refined function

Page 17: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Predicates

Quantifier-Free Logic of Uninterpreted Functions & Linear Arithmetic

e := x, y, z, ... -- variables

| 0, 1, 2, ... -- constants

| e + e | c * e | ... -- arithmetic

| f e1 ... en -- uninterpreted function

Uninterpreted Functions

Page 18: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Predicates

Quantifier-Free Logic of Uninterpreted Functions & Linear Arithmetic

Given a Verification Condition (VC)

SMT solvers can decide if VC is Valid ("always true")

Page 19: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

An Example

Page 20: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Refinement Type Solving

Page 21: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Refinement Type Solving

Page 22: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Refinement Type Solving

Instantiate every element with a conjunction of the abstract domain

Page 23: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Refinement Type Solving

Page 24: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Refinement Type Solving

Instantiate every element with a conjunction of the abstract domain

Page 25: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Refinement Type Solving

Page 26: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Refinement Type Solving

Page 27: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Refinement Type Solving

Page 28: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Refinement Type Solving

Page 29: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Refinement Type Solving

Page 30: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Contributions

● We still have to find the bug after we know it exists

Our fault localization algorithm searches for a minimal unsatisfiable constraint set, whose constraints map to likely locations of the bug in the implementation.

● What about missing parts of the specification?

Our predicate discovery algorithm uses disjunctive interpolation to automatically expand the abstract domain by inferring predicate templates that serve as the refinement types of program expressions.

Page 31: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Fault Localization

Page 32: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Fault Localization Overview

Page 33: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Constraint Minimization

Page 34: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%
Page 35: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%
Page 36: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%
Page 37: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%
Page 38: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%
Page 39: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%
Page 40: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

What if neither half fails?

Page 41: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%
Page 42: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%
Page 43: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Page 44: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%
Page 45: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%
Page 46: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%
Page 47: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%
Page 48: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%
Page 49: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%
Page 50: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%
Page 51: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%
Page 52: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%
Page 53: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%
Page 54: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%
Page 55: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%
Page 56: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%
Page 57: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Fault Localization Evaluation

Page 58: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Fault Localization Accuracy

● Every location reported by the algorithm that is in the ground truth set is a true positive.

● Every location reported by the algorithm that is not is a false positive.

● We measure false positives relative to some tolerance level n: if an algorithm returns fewer than n spurious bug locations for a file, then the algorithm is not counted as having a false positive for that file.

Page 59: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Fault Localization Accuracy

Page 60: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Fault Localization Efficiency

Runtimes do not necessarily correlate with program sizes: processed the largest benchmark, red black trees, at around 6 seconds.

These numbers indicate reasonable scaling for larger programs: the time taken relates to the relevant partitions of the constraint graph, not the program overall.

s

s

s

s

s

s

Page 61: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Predicate Discovery

Page 62: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Craig's Interpolation Theorem

● If A, B mutually inconsistent, i.e., A ∧ B is unsatisfiable● Exists an interpolant, I● such that ⊨A → I and that I and B are mutually inconsistent● where atoms(I) ⊆ atoms(A) ∩ atoms(B).

Page 63: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Disjunctive Interpolation

● If A, B mutually inconsistent, i.e., A ∧ B is unsatisfiable● Exists an interpolant, I● such that ⊨A → I and that I and B are mutually inconsistent● where atoms(I) ⊆ atoms(A) ∩ atoms(B).

Rummer et al. generalize:

● Instead of pairs of formulas, one unsatisfiable formula● Any number of labelled subformulas

Page 64: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Predicate Discovery Overview

Page 65: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Triangular numbers, again

Page 66: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Constraints

Page 67: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Constraint Generation

Page 68: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Horn Constraints

Page 69: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Horn Constraints

Page 70: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Horn Constraints

= ¬ ( )

Page 71: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Unrolling Constraints

Page 72: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Unrolling Constraints

Page 73: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Unrolling Constraints

Page 74: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Unrolling Constraints

Page 75: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Interpolation

Page 76: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Interpolation

Page 77: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Interpolation

Page 78: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Interpolation

Page 79: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Predicate Discovery Evaluation

Page 80: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Predicate Discovery on k-bounded Programs

● Considered 21 microbenchmarks.● All 21 successful

○ including instances where Liquid Haskell alone would not have been able to verify the program.

● Median runtime of 0.1 seconds and a maximum of 7.1 seconds.

Page 81: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Predicate Discovery in General

● 23 microbenchmarks○ programs that were not k-bounded for any○ programs that were k-bounded, but for which we only permitted our algorithm i < k unrolling○ Unroll depth of 2

● In 22 of 23 cases, enough predicates to prove correctness● The one failing case involved a constraint that was not k-bounded for any k in

an implementation of merge sort; in this case the domain expansion was missing only one qualifier (out of ~100).

● Our algorithm took a median of 0.1 seconds and a maximum of 7.2seconds.

Page 82: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Conclusion

Page 83: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Conclusion

Our fault localization algorithm produces minimal false positives (almost half of which are a single spurious location) and is efficient enough to be used at compile-time. It is much more effective at fault localization than the Liquid Haskell type checker, localizing twice as many bugs overall and finding six times more “hard” bugs than the type checker.

Our predicate discovery algorithm is correct by construction on k-bounded instances, finding annotations that admit program verification. Together, our two algorithms significantly reduce the barrier to entry for using refinement types systems.

Page 84: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Questions?

Page 85: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Extra Slides

Page 86: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Key Insights

1. A bug captured at the type checking level can be seen as an inconsistency.2. The locations reported to the user should be minimal to prevent implicating

spurious program locations as faults.3. Minimal explanations implicate relevant locations.

Page 87: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Central Insight

We can use the structure of type constraints to better localize faults and to

fix incomplete specifications

Page 88: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%
Page 89: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Related Work

The SEMINAL tool by Lerner et al. [20] uses the OCaml type checker as an oracle in a search procedure to find well-typed programs that are syntactically similar to an input program that fails to type check, which are then used to construct helpful error messages. Our fault localization algorithm likewise uses the type checker as an oracle, but works on the set of constraints generated from the input program instead. Since the space of constraints is much smaller than the space of possible edits for a program, our algorithm can be more efficient than the SEMINAL tool without sacrificing the ability to find bugs.

Pavlinovic et al. [24] reduce fault localization into an instance of the MaxSAT problem by generating a set of assertions from the input program that are weighted by a ranking measure provided by the compiler. An SMT solver is used to find a minimum set of error clauses that can be mapped back to possible bug locations.

While the approach is successful in finding bugs in OCaml programs, it is unclear

how successfully it could be applied to more sophisticated type systems such as Liquid Haskell. Our algorithm avoids this problem by using the existing constraint set generated for type checking the input program.

Zhang and Myers [35] induce a labeled directed graph from a set of Hindley-Milner typing constraints and use Bayesian inference methods to analyze the graph and find likely bug locations. Our algorithm similarly constructs a graph from a set of Liquid Haskell typing constraints. While the approach is are effective for Hindley-Milner type systems, it is not clear how to extend it to more expressive type systems.

There is also a significant literature related to predicate discovery [13]. Bjørner et al. [3] review techniques for reducing program verification to Horn clause constraints, and review the state of the art in solving systems of Horn clauses. Unno and Kobayashi [29] describe a procedure for inferring dependent intersection types using interpolants. Rümmer et al. [27] describes the theory of disjunctive interpolation in great detail. We show how to extend disjunctive interpolation to account for potentially recursive refinement typing constraints in order to automatically synthesize refinements for recursive, polymorphic and higher-order programs manipulating sophisticated data structures.

Page 90: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Thesis

We can use the structure of type constraints to better localize faults and to

fix incomplete specifications

Page 91: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Thesis

We can use the structure of type constraints to better localize faults and to

fix incomplete specifications

Page 92: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Thesis

We can use the structure of type constraints to better localize faults and to

fix incomplete specifications

Page 93: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Bugs are Bad

● Bugs are Expensive○ Modifying code, correcting defects, and evolving code account for as

much as 90% of the total cost of software projects.

Page 94: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Bugs are Bad

● Bugs are Expensive○ Modifying code, correcting defects, and evolving code account for as

much as 90% of the total cost of software projects.

Page 95: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Predicates

Quantifier-Free Logic of Uninterpreted Functions & Linear Arithmetic

e := x, y, z, ... -- variables

| 0, 1, 2, ... -- constants

| e + e | c * e | ... -- arithmetic

| f e1 ... en -- uninterpreted function

Page 96: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Find the bug

This code doesn't compile. At a glance, can you find why?

(actual code written by a student)

Page 97: Finding and Fixing Bugs in Liquid Haskellweimerw/students/anish-ms...Bugs are Bad Bugs are Expensive Modifying code, correcting defects, and evolving code account for as much as 90%

Find the "bug"

This code doesn't compile. At a glance, can you find why?

(actual code written by a student)