Papers by Martin Sulzmann

Journal of Functional Programming, May 16, 2011
Advanced type system features, such as GADTs, type classes, and type families, have proven to be ... more Advanced type system features, such as GADTs, type classes, and type families, have proven to be invaluable language extensions for ensuring data invariants and program correctness. Unfortunately, they pose a tough problem for type inference when they are used as local type assumptions. Local type assumptions often result in the lack of principal types and cast the generalisation of local let-bindings prohibitively difficult to implement and specify. User-declared axioms only make this situation worse. In this article, we explain the problems and-perhaps controversially-argue for abandoning local let-binding generalisation. We give empirical results that local let generalisation is only sporadically used by Haskell programmers. Moving on, we present a novel constraint-based type inference approach for local type assumptions. Our system, called OutsideIn(X), is parameterised over the particular underlying constraint domain X, in the same way as HM(X). This stratification allows us to use a common metatheory and inference algorithm. OutsideIn(X) extends the constraints of X by introducing implication constraints on top. We describe the strategy for solving these implication constraints, which in turn relies on a constraint solver for X. We characterise the properties of the constraint solver for X so that the resulting algorithm only accepts programs with principal types, even when the type system specification accepts programs that do not enjoy principal types. Going beyond the general framework we give a particular constraint solver for X = type classes + GADTs + type families, a non-trivial challenge in its own right. This constraint solver has been implemented and distributed as part of GHC 7. Vytiniotis, Peyton Jones, Schrijvers, Sulzmann Contents 1 Introduction 2 The challenge we address 2.1 Modular type inference and principal types 2.2 The challenge of local constraints 2.3 The challenge of axiom schemes 2.4 Recovering principal types by enriching the type syntax 2.5 Summary 3 Constraint-based type systems 3.1 Syntax 3.2 Typing rules 3.3 Type soundness 3.4 Type inference, informally 3.5 Type inference, precisely 3.6 Soundness and principality of type inference 4 Constraint-based type systems with local assumptions 4.1 Data constructors with local constraints 4.2 let should not be generalised 4.3 Let (non)-generalization in practice 4.4 The lack of principal types 5 Type inference with OutsideIn(X) 5.1 Type inference, informally 5.2 Overview of the OutsideIn(X) solving algorithm 5.3 Top-level algorithmic rules 5.4 Generating constraints 5.5 Solving constraints 5.6 Variations on the design 5.7 Soundness and principality of type inference 6 Incompleteness and ambiguity 6.1 Incompleteness due to ambiguity 6.2 Incompleteness due to inconsistency 6.3 Incompleteness of the OutsideIn(X) strategy 6.4 Guess-free completeness 6.5 Our position on incompleteness and ambiguity 7 Instantiating X for GADTs, type classes, and type families 7.1 The entailment relation 7.2 Solving equality constraints is tricky 7.3 The simplifier 7.4 Rewriting constraints 7.5 The rule SIMPLES 7.6 Soundness and principality 7.7 Termination 8 Implementation 8.1 Evidence OutsideIn(X) 8.2 Brief sketch of the implementation 9 Related work 9.1 Constraint-based type inference 9.2 The special case of GADTs 9.3 The special case of multi-parameter type classes 9.4 Solving equalities involving type families 9.5 Let generalization for units of measure and type families 9.6 Ambiguity 9.7 Is the emphasis on principal types well-justified? 10 Future Work References

arXiv (Cornell University), Jul 19, 2023
The lock set method and the partial order method are two main approaches to guarantee that dynami... more The lock set method and the partial order method are two main approaches to guarantee that dynamic data race prediction remains efficient. There are many variations of these ideas. Common to all of them is the assumption that the events in a critical section belong to the same thread. We have evidence that critical sections in the wild do extend across thread boundaries even if the surrounding acquire and release events occur in the same thread. We introduce the novel concept of a cross-thread critical section to capture such situations, offer a theoretical comprehensive framework, and study their impact on state-of-the-art data race analyses. For the sound partial order relation WCP we can show that the soundness claim also applies to cross-thread critical sections. For DCtp the occurrence of cross-thread critical sections invalidates the soundness claim. For complete partial order relations such as WDP and PWR, cross-thread critical sections help to eliminate more false positives. The same (positive) impact applies to the lock set construction. Our experimental evaluation confirms that cross-thread critical sections arise in practice. For the complete relation PWR, we are able to reduce the number of false positives. The performance overhead incurred by tracking cross-thread critical sections slows down the analysis by 10%-20%, on average.
Lecture Notes in Computer Science, 2015
We extend Brzozowski derivatives and partial derivatives from regular expressions to \(\omega \)-... more We extend Brzozowski derivatives and partial derivatives from regular expressions to \(\omega \)-regular expressions and establish their basic properties. We observe that the existing derivative-based automaton constructions do not scale to \(\omega \)-regular expressions. We define a new variant of the partial derivative that operates on linear factors and prove that this variant gives rise to a translation from \(\omega \)-regular expressions to nondeterministic Buchi automata.
In this paper we present the first exception analysis for a non-strict language. We augment a sim... more In this paper we present the first exception analysis for a non-strict language. We augment a simply-typed functional language with exceptions, and show that we can define a type-based inference system to detect uncaught exceptions. We have implemented this exception analysis in the GHC compiler for Haskell, which has been recently extended with exceptions. We give empirical evidence that the analysis is practical.
arXiv (Cornell University), Oct 25, 2015
We consider forkable regular expressions, which enrich regular expressions with a fork operator, ... more We consider forkable regular expressions, which enrich regular expressions with a fork operator, to establish a formal basis for static and dynamic analysis of the communication behavior of concurrent programs. We define a novel compositional semantics for forkable expressions, establish their fundamental properties, and define derivatives for them as a basis for the generation of automata, for matching, and for language containment tests. Forkable expressions may give rise to non-regular languages, in general, but we identify sufficient conditions on expressions that guarantee finiteness of the automata construction via derivatives.

arXiv (Cornell University), Oct 18, 2017
Linear Temporal Logic (LTL) is a widely used specification framework for linear time properties o... more Linear Temporal Logic (LTL) is a widely used specification framework for linear time properties of systems. The standard approach for verifying such properties is by transforming LTL formulae to suitable ω-automata and then applying model checking. We revisit Vardi's transformation of an LTL formula to an alternating ω-automaton and Wolper's LTL tableau method for satisfiability checking. We observe that both constructions effectively rely on a decomposition of formulae into linear factors. Linear factors have been introduced previously by Antimirov in the context of regular expressions. We establish the notion of linear factors for LTL and verify essential properties such as expansion and finiteness. Our results shed new insights on the connection between the construction of alternating ω-automata and semantic tableaux. Proof. First part. By induction on ϕ we show that {ϕ ′ | µ, ϕ ′ ∈ lf(ϕ)} ⊆ S(∂ + (ϕ)). Case tt. lf(tt) = { tt, tt } and tt ∈ S(∂ + (tt)). Case ℓ. Analogous. Case ff. Holds vacuously. Case ϕ ∨ ψ. Immediate by induction. Case ϕ ∧ ψ. Immediate by induction. Case ϕ. lf(ϕ) = { tt, ϕ ′ | ϕ ′ ∈ T (ϕ)} and by Lemma 6, T (ϕ) ⊆ S(∂ + (ϕ)). Case ϕ U ψ. lf(ϕ U ψ) = lf(ψ) ∪ { µ, ϕ ′ ∧ ϕ U ψ | µ, ϕ ′ ∈ lf(ϕ)}. By induction, the second components of lf(ψ) are in S(∂ + (ψ)) ⊆ S(∂ + (ϕ U ψ)). By induction, the second components ϕ ′ of lf(ϕ) are in S(∂ + (ϕ)), so that ϕ ′ ∧ ϕ U ψ ∈ S(∂ + (ϕ) ∪ {ϕ U ψ}) ⊆ S(∂ + (ϕ U ψ)). Case ϕ R ψ. lf(ϕ R ψ) = { µ⊙ν, ϕ ′ ∧ψ ′ | µ, ϕ ′ ∈ lf(ϕ), ν, ψ ′ ∈ lf(ψ)}∪ { ν, ψ ′ ∧ ϕ R ψ | ν, ψ ′ ∈ lf(ψ)}. By induction ϕ ′ ∈ S(∂ + (ϕ)) and ψ ′ ∈ S(∂ + (ψ)) so that ϕ ′ ∧ ψ ′ ∈ S(∂ + (ϕ) ∪ ∂ + (ψ)) ⊆ S(∂ + (ϕ R ψ)). Furthermore, ψ ′ ∧ ϕ R ψ ∈ S(∂ + (ψ) ∪ {ϕ R ψ}) ⊆ S(∂ + (ϕ R ψ)). Second part. By induction on ϕ. Case ℓ. If ϕ ′ = ℓ or ϕ ′ = tt, then tt ∈ S(∂ + (ℓ)). Case tt. Analogous. Case ff. Vacuously true. Case ϕ ∨ ψ. Immediate by induction. Case ϕ ∧ ψ. Immediate by induction. Case ϕ U ψ. By induction and the first part. Case ϕ R ψ. By induction and the first part. 6.7 Proof of Theorem 3 Proof. Suppose that σ |= ϕ. Show by induction on ϕ that σ ∈ L(A(ϕ)). Case tt. Accepted by run tt, tt,. .. which visits tt ∈ F infinitely often. Case ff. No run. Case p. As p ∈ I(σ 0), σ is accepted by run p, tt, tt,. .. . Case ¬p. Accepted by run ¬p, tt, tt,. .. . Case ϕ ∧ ψ. By definition σ |= ϕ and σ |= ψ. By induction, there are accepting runs α 0 , α 1 ,. .. on σ in A(ϕ) and β 0 , β 1 ,. .. on σ in A(ψ). But then α 0 ∧ β 0 , α 1 ∧ β 1 ,. .. is an accepting run on σ in A(ϕ ∧ ψ) because the state sets of the automata are disjoint.

Trends in Functional Programming, 2009
Previous work on type inference for functional dependencies demands that the dependency must full... more Previous work on type inference for functional dependencies demands that the dependency must fully cover all parameters of a type class to guarantee that the constraint solver is confluent. However, several interesting programs rely on non-full functional dependencies, For these, the underlying constraint is nonconfluent, and hence type inference for these programs is possibly ill-behaved. We investigate two approaches to restore confluence for non-full FDs. In the first approach, we characterize a class of transformable non-full to full FD programs where the resulting full FD program is confluent. This approach has some inherent limitations due to the use of constraint simplification during type inference. In the second approach, we show how achieve confluence in general by applying a radically different type-inference approach which favors constraint propagation over simplification. Our results provide new insights in type-inference issues behind functional dependencies and help to clarify some of the ongoing discussions about the possible adoption of functional dependencies in a future Haskell standard.

Springer eBooks, 2008
The actor model provides high-level concurrency abstractions to coordinate simultaneous computati... more The actor model provides high-level concurrency abstractions to coordinate simultaneous computations by message passing. Languages implementing the actor model such as Erlang commonly only support single-headed pattern matching over received messages. We propose and design an extension of Erlang style actors with receive clauses containing multi-headed message patterns. Patterns may be non-linear and constrained by guards. We provide a number of examples to show the usefulness of the extension. We also explore the design space for multi-headed message matching semantics, for example first-match and rule priority-match semantics. The various semantics are inspired by the multi-set constraint matching semantics found in Constraint Handling Rules. This provides us with a formal model to study actors with multiheaded message receive patterns. The system can be implemented efficiently and we have built a prototype as a library-extension to Haskell.
Sigplan Notices, Sep 17, 2002
We present a minimal extension of the Hindley/Milner system to allow for overloading of identifie... more We present a minimal extension of the Hindley/Milner system to allow for overloading of identifiers. Our approach relies on a combination of the HM(X) type system framework with Constraint Handling Rules (CHRs). CHRs are a declarative language for writing incremental constraint solvers. CHRs allow us to precisely describe the relationships among overloaded identifiers. Under some sufficient conditions on the CHRs we achieve decidable type inference and the semantic meaning of programs is unambiguous. Our approach allows us to combine open and closed world overloading. We also show how to deal with overlapping definitions.
Sigplan Notices, Aug 31, 2009
GADTs have proven to be an invaluable language extension, for ensuring data invariants and progra... more GADTs have proven to be an invaluable language extension, for ensuring data invariants and program correctness among others. Unfortunately, they pose a tough problem for type inference: we lose the principal-type property, which is necessary for modular type inference. We present a novel and simplified type inference approach for local type assumptions from GADT pattern matches. Our approach is complete and decidable, while more liberal than previous such approaches.

arXiv (Cornell University), Jun 20, 2022
Featherweight Go (FG) is a minimal core calculus that includes essential Go features such as over... more Featherweight Go (FG) is a minimal core calculus that includes essential Go features such as overloaded methods and interface types. The most straightforward semantic description of the dynamic behavior of FG programs is to resolve method calls based on run-time type information. A more efficient approach is to apply a type-directed translation scheme where interface-values are replaced by dictionaries that contain concrete method definitions. Thus, method calls can be resolved by a simple lookup of the method definition in the dictionary. Establishing that the target program obtained via the type-directed translation scheme preserves the semantics of the original FG program is an important task. To establish this property we employ logical relations that are indexed by types to relate source and target programs. We provide rigorous proofs and give a detailed discussion of the many subtle corners that we have encountered including the need for a step index due to recursive interfaces and method definitions.
We discuss type classes in the context of the Chameleon language, a Haskell-style language where ... more We discuss type classes in the context of the Chameleon language, a Haskell-style language where overloading resolution is expressed in terms of the meta-language of Constraint Handling Rules (CHRs). In a first step, we show how to encode Haskell’s single-parameter type classes into Chameleon. The encoding works by providing an approrpriate set of CHRs which mimic the Haskell conditions. We also consider constructor classes, multi-parameter type classes and functional dependencies. Chameleon provides a testbed to experiment with new overloading features. We show how some novel features such as universal quantification in context can naturally be expressed in Chameleon. 1.
Proceedings of the 2019 ACM SIGPLAN Workshop on Partial Evaluation and Program Manipulation, 2019
Futures and promises are a high-level concurrency construct to aid the user in writing scalable a... more Futures and promises are a high-level concurrency construct to aid the user in writing scalable and correct asynchronous programs. We introduce a simple core language based on which we can derive a rich set of future and promise features. We discuss ways to implement the core features via shared-state concurrency making either use of Software Transactional Memory, an elementary lock-based primitive, or an atomic compare-and-swap operation. The approach has been fully implemented in Haskell and Scala. For both languages, we provide empirical evidence of the effectiveness of our method. We consider program transformations in the context of futures and promises and observe potential problems in existing Scala-based libraries.
Happens-before based data race prediction methods infer from a trace of events a partial order to... more Happens-before based data race prediction methods infer from a trace of events a partial order to check if one event happens before another event. If two write events are unordered, they are in a race. We observe that common tracing methods provide no guarantee that the trace order corresponds to an actual program run. We refer to this as an inaccurate trace. The consequence of inaccurate tracing is that results (races) reported are inaccurate. We introduce diagnostic methods to examine if (1) a race is guaranteed to be correct regardless of any potential inaccuracies, (2) maybe is incorrect due to inaccurate tracing. We have fully implemented the approach and provide for an empirical comparison with state of the art happens-before based race predictors such as FastTrack and SHB.

ArXiv, 2020
Ensuring the correct visual appearance of graphical user interfaces (GUIs) is important because v... more Ensuring the correct visual appearance of graphical user interfaces (GUIs) is important because visual bugs can cause substantial losses for businesses. An application might behave functionally correct in an automated test, but visual bugs can make the GUI effectively unusable for the user. Most of today's approaches for visual testing are pixel-based and tend to have flaws that are characteristic for image differencing. For instance, minor and unimportant visual changes often cause false positives, which confuse the user with unnecessary error reports. Our idea is to introduce an abstract GUI state (AGS), where we define structural relations to identify relevant GUI changes and ignore those that are unimportant from the user's point of view. In addition, we explore several strategies to address the GUI element identification problem in terms of AGS. This allows us to provide rich diagnostic information that help the user to better interpret changes. Based on the principles ...
Solving of regular equations via Arden’s Lemma is folklore knowledge. We first give a concise alg... more Solving of regular equations via Arden’s Lemma is folklore knowledge. We first give a concise algorithmic specification of all elementary solving steps. We then discuss a computational interpretation of solving in terms of coercions that transform parse trees of regular equations into parse trees of solutions. Thus, we can identify some conditions on the shape of regular equations under which resulting solutions are unambiguous. We apply our result to convert a DFA to an unambiguous regular expression. In addition, we show that operations such as subtraction and shuffling can be expressed via some appropriate set of regular equations. Thus, we obtain direct (algebraic) methods without having to convert to and from finite automaton.
Events based on channel communications and futures/promises are powerful but seemingly different ... more Events based on channel communications and futures/promises are powerful but seemingly different concepts for concurrent programming. We show that one concept can be expressed in terms of the other with surprisingly little effort. Our results offer light-weight library based approaches to implement events and futures/promises. Empirical results show that our approach works well in practice.
We introduce System FC, which extends System F with support for non-syntactic type equality. Ther... more We introduce System FC, which extends System F with support for non-syntactic type equality. There are two main extensions: (i) explicit witnesses for type equalities, and (ii) open, non-parametric type functions, given meaning by top-level equality axioms. Unlike System F, FC is expressive enough to serve as a target for several different source-language features, including Haskell’s newtype, generalised algebraic data types, associated types, functional dependencies, and perhaps more besides. NOTE: this version has a substantial Appendix, written subsequent to the publication of the paper, giving a simplified version of System FC. This version is much closer to the one used in GHC.
Uploads
Papers by Martin Sulzmann