with Expansion Variables and Intersection Types in System E and an Exact Correspondence with β-Reduction∗

Sebastien´ Carlier J. B. Wells Heriot-Watt University Heriot-Watt University http://www.macs.hw.ac.uk/~sebc/ http://www.macs.hw.ac.uk/~jbw/

ABSTRACT 1. DISCUSSION System E is a recently designed type system for the λ- calculus with intersection types and expansion variables. Dur- 1.1 Background and Motivation ing automatic type inference, expansion variables allow post- poning decisions about which non-syntax-driven typing rules 1.1.1 Types for Programs and Type Inference to use until the right information is available and allow im- Types have been used extensively to analyze computer plementing the choices via substitution. program properties without executing the programs, for pur- This paper uses expansion variables in a unification-based poses such as detecting programming errors, enforcing ab- automatic type inference algorithm for System E that suc- stract inter-module interfaces, justifying compiler optimiza- ceeds for every β-normalizable λ-term. We have imple- tions, and enforcing security properties. mented and tested our algorithm and released our implemen- In the type assignment style, a type system associates each tation publicly. Each step of our unification algorithm corre- untyped (i.e., free of type annotations) term (e.g., computer sponds to exactly one β-reduction step, and vice versa. This program fragment) with 0 or more typings, where each typ- formally verifies and makes precise a step-for-step correspon- ing is a pair of a result type and a type environment for free dence between type inference and β-reduction. This also term variables. Type inference is finding a typing to assign shows that type inference with intersection types and expan- to an untyped term, if possible. Type inference provides the sion variables can, in effect, carry out an arbitrary amount benefits of types while relieving programmers from having of partial evaluation of the program being analyzed. to manually supply the types. Type inference algorithms generally solve constraints, of- Categories and Subject Descriptors ten by unification, the process of computing a solution (if one exists) that assigns values to variables so that con- D.3.1 [Programming Languages]: Formal Definitions and straints become solved. Unification-based type inference is Theory; F.4.1 [Theory of Computation]: Mathematical usually understandable and often efficiently implementable. Logic— and related systems; F.3.2 [Logics The most widely used type inference algorithm is Milner’s and Meanings of Programs]: Semantics of Programming W for the well known Hindley/Milner (HM) system [27], Languages—Program analysis. used in languages such as SML, OCaml, and Haskell. The amount of polymorphism provided by HM is equiva- General Terms lent to unfolding all let-expressions (a form of partial eval- Algorithms, languages, theory. uation) and then doing type inference with simple types. HM-style polymorphism is not implemented by unfolding let-expressions because (1) this is difficult to combine with Keywords separate compilation and (2) it is very inefficient as it re- Lambda-calculus, type inference, intersection types, expan- analyzes let-expressions every time they are used. HM has sion variables. simple and efficient (for typical cases) type inference and supports separate compilation provided module interfaces ∗ are given. However, HM is somewhat inflexible and does Partially supported by EC FP5/IST/FET grant IST-2001- not support compositional analysis, i.e., analyzing modules 33477 “DART”, NSF grant 0113193 (ITR), and Sun Mi- without knowledge about other modules. crosystems equipment grant EDUD-7826-990410-US. 1.1.2 Intersection Types Intersection types were introduced for the λ-calculus by Permission to make digital or hard copies of all or part of this work for Coppo and Dezani [8] and independently by Pottinger [29]. personal or classroom use is granted without fee provided that copies are In both cases, a major motivation was the connection be- not made or distributed for profit or commercial advantage and that copies tween β-reduction and intersection types, which makes in- bear this notice and the full citation on the first page. To copy otherwise, to tersection types well suited for program analysis. republish, to post on servers or to redistribute to lists, requires prior specific Intersection type systems have been developed for many permission and/or a fee. PPDP '04, 2004-08-24/---26, Verona, Italy. kinds of program analysis (e.g., flow [1], strictness [18], dead- Copyright 2004 ACM 1-58113-819-9/04/0008 ...$5.00. code [13, 10], and totality [7]) usable for justifying compiler optimizations to produce better machine code. Intersection tance of principal typings. Damiani [11] has extended sup- types seem to have the potential to be a general, flexible port for conditionals and letrec (mutually recursive bind- framework for many program analyses. ings) as well as support for a let-binding mechanism that In most intersection type systems, every typable term has effectively adds some of the power of one more rank to ob- a principal typing [37], one that is stronger than all other tain some of the expressiveness of rank-3 intersection types. typings assignable to that term. Principal typings improve Damiani [12] has also worked on rank-2 intersection types the possibilities of analyzing programs incrementally and for symmetric linking of modules. minimizing reanalysis cost after program modifications. Restricting intersection types to rank-2 does not use their full potential to analyze programs as precisely as needed, so 1.1.3 Type Inference for Full Intersection Types we do not pursue this idea. The first type inference algorithms for intersection type systems were by Coppo, Dezani and Venneri [9], and Ronchi 1.1.5 Expansion Variables della Rocca and Venneri [32]. These algorithms give princi- Kfoury and Wells [20, 22] gave a type inference algo- pal typings for β-normal forms, and it is separately proven rithm for System I, a full, non-rank-restricted intersection that a principal typing for a term’s β-normal form is also type system. System I introduced expansion variables and principal for the term. One disadvantage of this approach is a single operation integrating expansion and substitution; that terms must be reduced to β-normal form before types together, these features vastly simplified expansion. are found for them. Another disadvantage is that getting Unfortunately, System I has several technical limitations. other typings from principal typings in this approach uses The substitution operation (which contains expansion) has operations such as substitution, expansion, and lifting, and a built-in renaming (needed for complete type inference) the older expansion definitions are hard to understand. of type and expansion variables that prevents substitutions Ronchi della Rocca [31] devised the first unification-based from being composable. An awkward workaround for this type inference algorithm for a non-rank-restricted intersec- problem called safe composition was developed, but safe tion type system. This algorithm yields principal typings composition is hard to understand and people have been when it succeeds. Because typability for the full system error-prone when working with it. System I has other techni- is undecidable, the algorithm is of course sometimes non- cal limitations such as non-associative and non-commutative terminating; to ensure termination, one can restrict type intersections and no weakening; together, these limitations height. This algorithm uses the older, complicated defini- prevent it from having subject reduction. tion of expansion, which has several disadvantages: (1) the The recently developed System E [6] improves in many unification procedure requires global knowledge in addition ways on System I. The full System E (only a fraction of to the two types to unify, which makes the technique delicate its power is needed for this paper) is more flexible than the to extend; (2) expansion is only defined on types and typ- extremely flexible intersection type system of Barendregt, ings, but not on typing derivations (needed for use in com- Coppo, and Dezani [2]. Contrary to Van Bakel’s advice to piler optimizations), which are thus not straightforward to make intersection type systems as lean as possible [36], Sys- obtain via type inference; (3) the older notion of expansion tem E does not restrict where intersection type constructors only allows intersection introduction in argument position, (and thus also expansion variables) can be used. Flexible and is thus unsuitable for accurate resource tracking under expansion variable placement allows expansion variables to call-by-need and call-by-value evaluation. establish namespaces. In turn, this allows a substantially Regnier [30] presented an inference algorithm for an in- simpler way of integrating expansion and substitution. In tersection type system called De. System De is similar to particular, System E does not need the automatic built-in that of [31], with the essential addition of labels in types fresh-renaming done during expansion in System I. As a to carry out expansion. Using nets, an untyped version of result, substitution and expansion in System E are more ro- proof nets from Linear Logic [14], Regnier showed an ex- bust than they are in System I and composition works for act correspondence between net reduction in Linear Logic substitutions and expansions. These improvements make it and type inference in System De. Boudol and Zimmer [4] much simpler to design type inference methods for System E, gave an inference algorithm that implements expansion by leading to the new results in this paper. attaching a set of type variables to each typing constraint; this appears to be hard to generalize beyond pure λ-calculus. 1.2 Summary of Contributions Both the approach of Regnier and that of Boudol and Zim- 1. We present a clear and precise unification-based inter- mer are stated to be unification-based, but neither approach section type inference algorithm in System E and prove produces unifiers (substitutions that solve unification con- that it types any β-normalizing λ-term. We believe our straints); this makes them less practical. presentation is easier to understand and implement than other presentations of intersection type inference. It is a 1.1.4 Rank-2 Intersection Types strength of our algorithm that it needs only the !-free frag- Leivant [23] introduced a rank-2 intersection type system ment of System E restricted to trivial subtyping. (Our and remarked that it is similar in typing power to Hind- algorithm works unchanged with these features present.) ley/Milner. In fact, rank-2 intersection type systems type 2. Our intersection type inference approach provides a sim- strictly more terms than Hindley/Milner, although the ad- ple and clean step-for-step β-reduction/unification corre- ditional terms are not very significant. spondence. In the main algorithm phase, each step of Van Bakel [35] gave the first unification-based type infer- our unify-β rule on constraints corresponds to exactly ence algorithm for a rank-2 intersection type system. Jim [19] one β-reduction step on λ-terms, and vice versa. Any studied extensions of rank-2 intersection type systems with β-reduction strategy can be simulated by a strategy of practical programming features and discussed the impor- using unify-β, and vice versa. Our proof that our algo- rithm succeeds for all β-normalizing λ-terms takes ad- suitable to be extended to have flexible analysis precision vantage of this correspondence and uses the well known and to analyze call-by-need and call-by-value behavior. β-normalizing leftmost/outermost strategy. This corre- 10. We have implemented all of the algorithms described in spondence is impossible for systems without the flexibility this paper and made them available via a web interface [5] of intersection types, because they can not type even all and for downloading (http://www.macs.hw.ac.uk/DART/ strongly β-normalizing terms [34]. Our correspondence software/system-e/). Our implementation generated improves over that of Regnier [30] both by being more the example output found in appendix A. formal and also by being direct instead of being the com- 11. A technical report with full proofs will be made available position of two correspondences with untyped nets as an on the web pages of the authors by 2004-08. intermediate notion. The clear presentation of this correspondence helps to 1.3 Ongoing Future Work share the understanding that any intersection type in- The full System E (only part is presented in this pa- ference approach will be equivalent to partial evaluation per) has the ! type constructor which allows non-exact anal- followed by a monovariant analysis. In effect, intersection ysis. The step-for-step β-reduction/unification correspon- type inference can do an arbitrary amount of partial eval- dence means that type inference can obtain polyvariance uation via type unification, i.e., it can do the equivalent by doing the equivalent of any amount of partial evaluation of any amount of β-reduction of the analyzed term. of the analyzed program followed by a cruder, more tradi- 3. Our intersection type inference approach is the only one tional monovariant analysis that uses ! and subtyping to col- to provide a notion of readback that allows extracting β- lapse the analysis. Because of the careful way ! is integrated reduced λ-terms from partially solved constraints during into the full System E, the analysis results precisely indicate type inference. This makes it easy to prove the step-for- where the information is exact and where it is approximate. step β-reduction/unification correspondence and makes This ability for type inference to partially evaluate leads the correspondence easier to understand. The use of read- to the potential of analysis that simultaneously is compo- back makes our approach clearer than the approaches of sitional and has easily adjustable cost and precision. (The Boudol and Zimmer [4] and also Regnier [30]. algorithm presented in this paper always has exact precision 4. Unlike early algorithms from before 1990, our inference and the same cost as normalization.) In contrast, the widely algorithm can build and use expansions based solely on used algorithm W for Hindley/Milner is non-compositional local matching of constraint solving rules without needing and does the equivalent of a fixed amount of partial evalua- global knowledge of the typing inferred so far, because tion (unfolding all let-expressions) followed by the standard expansion in System E is guided by E-variables. (monovariant) first-order unification of simple type infer- 5. The statements and proofs of properties of our inference ence [25]; all information in the results must be assumed to algorithm are made clearer and more precise by the use be approximate. Although we have left the full exploration of skeletons, compact syntactic representations of typing of this promising possibility to future work, this motivation derivations. Unlike System E, nearly all other intersection helps justify the significance of this work. Investigating this type systems do not have skeletons. is ongoing work with our colleague Makholm. 6. Our inference algorithm builds a solution that solves the Because in System E expansion can occur in non-function- input constraints, i.e., a substitution of types for type argument positions, type inference will be able to do resource- variables and expansions for E-variables that when ap- aware analysis of call-by-need and call-by-value evaluation, plied to the input constraints yields satisfied constraints. rather than being applicable only to call-by-name evaluation This is only possible because the composition of expan- (which is unused in practice). sions and substitutions is straightforward in System E, We believe the algorithm Infer (definition 4.22) finds so- which is not true for other systems. lutions that yield principal typings [37]. Proving this is on- 7. Our algorithm can easily be used to get different forms going work with our colleagues Kfoury and Bakewell. of output such as a full typing derivation or just a typing (result type and type environment) because expansion is 1.4 Other Future Work defined on all of the mathematical entities in System E, Because types are often exposed to programmers, a major including skeletons. Constructing typing derivations is design goal for many type systems has been making types vital for use in compilers with typed intermediate repre- suitable for human comprehension. Unfortunately, this con- sentations. In contrast, many presentations of other algo- flicts with making types suitable for accurate and flexible rithms do not clearly document how to construct typing program analysis. Intersection types are good for accurate derivations; this knowledge is either buried deep inside analysis. However, inferred intersection types may be ex- proofs or simply omitted. tremely detailed and thus are likely to be unsuitable for pre- 8. Our inference algorithm manages analysis polyvariance senting to humans. Alternative type error reporting meth- by a scheme of properly arranging the nesting of a finite ods such as type error slicing [15, 16] can avoid presenting number of E-variables. This is simpler than renaming these types directly to programmers. Investigation is needed schemes used in other approaches and greatly eases imple- to combine type error slicing with System E. mentation. This is only possible because, unlike previous Module boundary interfaces are generally intended to ab- intersection type systems, System E has no restrictions stract away from the actual software on either side of the on where expansion can occur. Expansion in System E interface, so that implementations can be switched. Also, can splice intersection constructors into type positions module boundary interfaces must be compact and easily un- that are to the right of arrows and into typing derivation derstandable by humans. For these reasons, ∀ and ∃ quan- positions that are not function application arguments. tifiers are appropriate for use in module boundary types. 9. As explained below in sec. 1.3, our algorithm is more An open problem is how to use very flexible and accurate types such as intersection types for analysis and then check Given an order < on a set X, let the lexicographic-extension ∗ whether they imply types using ∀ and ∃ quantifiers. order

Figure 1: Syntax grammars and metavariable conventions.

[E1 ∩. E2] X = [E1] X ∩. [E2] X [] α = α [S] e X = [[S] e] X [e E] X = e [E] X [] e = e  [ω] Y = ω [v := Φ, S] v0 = [S] v0 if v 6= v0 [S]  = S [ω] Q = ωterm(Q) [v := Φ, S] v = Φ [S] (v := Φ, S0) = (v := [S] Φ, [S] S0) :τ :[S] τ [S] (X1 ∩. X2) = [S] X1 ∩. [S] X2 [S] ω = ω [S] x = x M M [S] (τ1 l τ2) = [S] τ1 l [S] τ2 [S] ω = ω [S] λx. Q = λx. [S] Q :τ :[S] τ [S] (τ1 → τ2) = [S] τ1 → [S] τ2 [S] Q = ([S] Q) [S] (Q1 @ Q2) = [S] Q1 @ [S] Q2

Figure 2: Expansion application.

Both α-conversion and the additional rules for types and Expansion is an operation that calculates for a typing judge- constraints are imposed as equalities, where “=” is mathe- ment the changed judgement that would result from insert- matical equality (as it should be). For example, ω ∩. α = α. ing additional typing rule uses at nested positions in the After this modification, the syntactic sorts no longer form judgement’s derivation. E-variables are a new technology an initial algebra, so care must be taken. that makes expansion simpler and easier to implement and reason about. E-variables are placeholders for unknown uses 3.3 Operations on Syntax of other typing rules like ∩. -introduction. E-variables are Let T v T 0 iff T 0 = T ∩. T 00 and let T w T 0 iff T 0 v T . propagated into the types and the type constraints used Let M[x := N] and respectively M −−→β N denote the usual by type inference algorithms. In System E, expansion op- notions [3] for untyped λ-terms of term-variable substitution erations are described by syntactic terms. The use of E- and respectively β-reduction. variables and expansion terms allows defining expansion ap- Let term be the least-defined function such that: plication in a precise, uniform, and syntax-directed way. term(x:τ ) = x Definition 3.3 (Expansion application). Fig. 2 defines term(λx. Q) = λx.term(Q) the application of substitutions to E-variables, and of expan- term(Q1 @ Q2) = term(Q1) @ term(Q2) sions to types, expansions, constraints, and skeletons. term(Q:τ ) = term(e Q) = term(Q) M Example 3.4. E-variables effectively establish namespaces term(ω ) = M and substituting an expansion for an E-variable can merge . term(Q1 ∩ Q2) = term(Q1) if term(Q1) = term(Q2) namespaces. Define the following:

A skeleton Q is well formed iff term(Q) is defined. E.g., Q = τ1 = e1 a0 → a0 S1 = (e1 := , ) S2 = (a0 := τ2, ) x:τ1 ∩. y:τ2 is ill-formed if x 6= y since term(Q) is undefined. Then these facts hold:

Convention 3.1. Henceforth, only well formed skeletons [S2] τ1 = e1 a0 → τ2 are considered. [S1] τ1 = a0 → a0 [S2] [S1] τ1 = τ2 → τ2 Definition 3.2. E-path If ∆˙ = ~e∆,¯ then E-path(∆)˙ = ~e is the E-path of ∆.˙ If D is a skeleton context, we define In [S2] τ1, the T-variable a0 inside the E-variable e1 is ef- E-path(D), the E-path of the context hole in D, by induc- fectively distinct from the T-variable a0 outside e1, so the tion, as follows: substitution only replaces the outer a0. The operation [S1] τ1 replaces e1 by the empty expansion (which is actually the 2 E-path( ) =  identity substitution), and this effectively lifts the inner a0 E-path(e D) = e · E-path(D) into the root namespace, so that [S2] [S1] τ1 replaces both :τ E-path(λx. D) = E-path(D ) = E-path(D @ Q) occurrences of a0. = E-path(Q @ D) = E-path(D ∩. Q) = E-path(Q ∩. D) = E-path(D) Lemma 3.5 (Expansion application composition). Given any E1, E2, X, [[E1] E2] X = [E1] [E2] X.

3.4 Expansion Application Let E1; E2 = [E2] E1 (composition of expansions). By The essential new notion of System E is the way it uses lem. 3.5, the “;” operator is associative. Although E1; E2 is expansion variables (E-variables) to implement expansion. not much shorter than [E2] E1, it is easier to follow. (M . Q) : hA ` τi / ∆ (abstraction) (variable) (λx.M . λx. Q) : hA[x 7→ ω] ` A(x) → τi / ∆ (x . x:τ ) : h(x : τ) ` τi / ω

(M1 . Q1) : hA1 ` τ2 → τ1i / ∆1; (M2 . Q2) : hA2 ` τ2i / ∆2 (application) (omega) M (M1 @ M2 . Q1 @ Q2) : hA1 ∩. A2 ` τ1i / ∆1 ∩. ∆2 (M . ω ) : henvω ` ωi / ω

(M . Q1) : hA1 ` τ1i / ∆1; (M . Q2) : hA2 ` τ2i / ∆2 (M . Q) : hA ` τi / ∆ (intersection) (E-variable) (M . Q1 ∩. Q2) : hA1 ∩. A2 ` τ1 ∩. τ2i / ∆1 ∩. ∆2 (M . e Q) : he A ` e τi / e ∆

(result (M . Q) : hA ` τ1i / ∆ :τ2 subtyping) (M . Q ) : hA ` τ2i / ∆ ∩. (τ1 l τ2)

Note: When these rules derive judgements of the form (M . Q) : hA ` τi / ∆ such that solved(∆) holds, then these rules act as typing rules in the traditional sense. (See also remark 3.10.)

Figure 3: Typing rules.

An assignment φ may stand for a substitution (φ, ) and a judgement for the untyped term term(Q). Using skele- is to be interpreted that way if necessary. The higher prece- tons avoids needing gigantic judgement trees in formal state- dence of (v := Φ) over (φ, S) also applies here. For exam- ments. Many type systems use type-annotated λ-terms for ple, as a substitution (e1 := e2 := S2, e3 := S3) stands for this role, but this fails for typing rules like our intersection ((e1 := (e2 := S2)), e3 := S3) which can be written in full as (∩. -introduction) rule. (See [38, 39] for a discussion.) ((e1 := ((e2 := S2), )), (e3 := S3), ). The intended meaning of (M . Q) : hA ` τi / ∆ is that Q Let e/S stand for (e := e S). Thus, when necessary, e/S is a proof that the untyped term M has the typing hA ` τi, stands for ((e := e S), ). The “/” notation builds a substi- provided the constraint ∆ is solved w.r.t. some subtyping tution that affects variables underneath an E-variable, be- relation. The typing rules do not check whether a constraint cause [e/S] e X = e [S] X. E.g., S = (e0/(a1 := τ1), a0 := τ0) ∆ is solved to allow (1) using different subtyping relations stands for S = (e0 := e0 (a1 := τ1, ), a0 := τ0, ) and in and (2) using the same rules to generate constraints to be this case it holds that [S] (e0 a1 → a0) = e0 τ1 → τ0. solved by type inference. For a subtyping relation, this paper We extend this notation to E-variable sequences so that needs and will use only the weakest, namely equality on ~e · e/S stands for ~e/e/S and /S stands for S. types, but other papers on System E use other relations (e.g., ≤nlin and ≤flex from [6]). The results in this paper 3.5 Type Environments and Typing Rules extend to all subtyping relations that include equality. Type environments, ranged over by A and B, are total functions from Term-Variable to Type that map only a finite Definition 3.8 (Valid skeleton). A skeleton Q is valid iff number of variables to non-ω types. there exist M, A, τ, and ∆ s.t. (M . Q) : hA ` τi / ∆.

Definition 3.6 (Operations on type environments). Convention 3.9. Only valid skeletons are considered. [E] A = { (x, [E] A(x)) x ∈ Term-Variable } A skeleton Q uniquely determines all components in its A ∩. B = { (x, A(x) ∩. B(x)) x ∈ Term-Variable } judgement. Let typing, constraint, tenv, and rtype be func- e A = { (x, e A(x)) x ∈ Term-Variable } tions s.t. (M . Q) : hA ` τi / ∆ implies typing(Q) = hA ` τi, envω = { (x, ω) x ∈ Term-Variable } constraint(Q) = ∆, tenv(Q) = A, and rtype(Q) = τ. Let (x1 : τ1, . . . , xn : τn) be envω[x1 7→ τ1] · · ·[xn 7→ τn]. Ob- A constraint ∆ is solved, written solved(∆), iff ∆ is of the serve, for every e, E1, E2, A, and x, that (1) [E1 ∩. E2] A = form ~e1 (τ1 l τ1) ∩. · · · ∩. ~en (τn l τn). Given a judgement [E1] A∩. [E2] A, (2) [E] (A ∩. B) = [E] A∩. [E] B, (3) [e ] A = (M . Q) : hA ` τi / ∆, the entire judgement and its skeleton e A, (4) (e A)(x) = e A(x), (5) [ω] A = envω, and finally (6) Q are solved iff ∆ is solved. The unsolved part of a constraint [E] A[x 7→ τ] = ([E] A)[x 7→ [E] τ]. ∆, written unsolved(∆), is the smallest constraint ∆1 such that ∆ = ∆1 ∩. ∆2 and solved(∆2) for some ∆2. Definition 3.7 (Typing judgements and typing rules). Fig. 3 gives the typing rules of System E used in this paper. Remark 3.10 (Relation to traditional typing rules). The rules derive judgements of the following form with the Solved judgements and skeletons correspond respectively to indicated components: traditional typing judgements and derivations. Traditional typing typing rules are merely the special case of the typing rules in fig. 3 where all constraints are solved. When constraints (M . Q) : hA ` τi / ∆ are solved, our use of “typing” for a pair hA`τi matches the definition in [37]. The rules in fig. 3 can also be used to gen- untyped term constraint erate unsolved constraints to be solved by a type inference skeleton result type type environment algorithm, as is done in sec. 4. Our presentation not only saves space by combining the two roles of the rules, but also A pair hA ` τi of a type environment A and a result type τ guarantees in a simple way (stated formally in lem. 3.11) is a typing. that type inference yields valid typing derivations. A skeleton Q is just a proof term, a compact notation representing an entire typing derivation. A skeleton Q syn- Lemma 3.11 (Admissibility of expansion). If (M .Q) : tacticly represents a tree of typing rule uses that derives hA ` τi / ∆, then (M . [E] Q) : h[E] A ` [E] τi / [E] ∆. 4. TYPE INFERENCE Definition 4.4 (Readback). Let readback be the least- This section presents a type inference algorithm for Sys- defined function where readback(A, τ, ∆) is given by case tem E. We show how to infer a typing for any normalizing analysis on τ and subsequently on ∆ if τ = a0, such that: untyped λ-term M, where each constraint-solving step ex- :a0 readback((x : a0), a0, ω) = x actly corresponds to one β-reduction step, starting from M. readback(e0 A, e0 τ1 → e0 τ2, e0 ∆) = λx. e0 Q We also give an algorithm that reconstructs the β-reduced if A(x) = ω term from each intermediate stage of type inference. and Q = readback(A[x 7→ τ1], τ2, ∆) The approach to type inference is as follows. Given an readback(e1 A1 ∩. e2 A2, a0, untyped term M as input, (1) pick an initial skeleton Q such e1 ∆1 ∩. e2 ∆2 ∩. (e1 τ1 l e2 τ2 → a0) that term(Q) = M, (2) do unification to find a substitution :e2 τ2→a0 = (e1 Q1) @ e2 Q2 S solving constraint(Q), and (3) use Q and S to calculate a if Q1 = readback(A1, τ1, ∆1) solved skeleton (typing derivation) or a typing for M. and Q2 = readback(A2, τ2, ∆2) If run on λ-terms which have no normal form, our in- ference algorithm is non-terminating. This also makes it For convenience, we let readback(Q) = readback(tenv(Q), in some sense incomplete because any term, even if it is rtype(Q), unsolved(constraint(Q))). non-normalizable, can be typed using the ω typing rule in System E. Example 4.5 (Readback). Let A = (z : e2 a0), τ = a0 and: l 4.1 Initial Skeletons ∆ = (e1 (e0 a0 → e0 a0) e2 a0 → a0) ∩. (e ( (e a → e a ) → e a → e a We pick an initial skeleton initial(M) using three distinct 1 0 0 0 0 0 0 0 0 l (e0 a0 → e0 a0) → e0 a0 → e0 a0)) E-variables e0, e1, and e2, and one T-variable a0, as follows: We have: initial(x) = x:a0 :a0 initial(λx.M) = let Q = e0 initial(M) readback(A, τ, ∆) = (e1 (λx. e0 (x )) : e2 a0 → a0) :a0 „in λx. Q « @ e2 (z ) initial(M @ N) = let Q1 = e1 initial(M) 0 Q2 = e2 initial(N) 1 Lemma 4.6 (Readback builds pleasant skeletons). If → in Q :rtype(Q2) a0 @ Q readback(A, τ, ∆) = Q, then Q = P for some P . @ 1 2A We extend this definition to contexts, taking initial(2) = 2. Lemma 4.7 (Readback is identity on pleasant skele- tons). If readback(P ) = P 0, then P 0 = P . Example 4.1 (Initial skeleton). Let M = (λx.x @ x)@y, Q = initial(M): Combining lemmas 4.3 and 4.7, we obtain this diagram: :a0 :a0 initial Q = ( e1 (λx. e0 ((e1 (x ) : e2 a0 → a0) @ e2 (x ))) M P readback : e2 a0 → a0) :a0 term @ e2 (y )

We have (M . Q) : hA ` τi / ∆ where A = (y : e2 a0), τ = Lemma 4.8 (Readback preserves typings). Suppose a0 and ∆ = (e1 (e0 e1 a0 ∩. e0 e2 a0 → e0 a0) l e2 a0 → a0) ∩. that readback(A, τ, ∆) = P and term(P ) = M. Then it (e1 e0 (e1 a0 l e2 a0 → a0)). holds that (M . P ) : hA ` τi / unsolved(∆). We now define pleasant skeletons, which syntacticly char- 4.3 Unification Rules acterize skeletons produced by initial. From fig. 1, the metavariable ∆˙ ranges over singular con- Definition 4.2 (Pleasant skeleton). A skeleton Q is pleas- straints, those that contain exactly one type inequality, and ant iff Q = P for some P defined as follows: ∆¯ ranges over singular constraints that have an empty E- path. Each unification step solves one singular constraint. :a0 :e2 τ→a0 P ::= x | λx. e0 P | (e1 P1) @ e2 P2 Fig. 4 introduces rules unify-β and unify-@, which are τ→ used to produce substitutions that solve singular constraints. Note that by convention 3.9, if P = (e P ):e2 a0 @ e P , 1 1 2 2 Observe that these rules mention 4 specific, fixed concrete then τ = rtype(P ). Note that this definition uses 4 specific, 2 E- and T-variables (e , e , e , a ), rather than arbitrary fixed concrete E- and T-variables (e , e , e , and a ). 0 1 2 0 0 1 2 0 metavariables e and α. (Originally, we made the rules match All constraints of a pleasant skeleton are unsolved, and arbitrary E-variables, but this generality was not actually for all x, tenv(P )(x) = ~e1 a0 ∩. · · · ∩. ~en a0 for some n ≥ 0. used and the proof is simpler this way.) We now study each of these two rules in detail. Lemma 4.3 (Properties of initial). 4.3.1 Rule unify-β 1. initial(M) is a pleasant skeleton. This section shows that rule unify-β solves constraints in a 2. If P = initial(M) then term(P ) = M. way that corresponds exactly with β-reduction on λ-terms. 3. If M = term(P ) then initial(M) = P . Rule unify-β matches on singular constraints of the form ∆¯ = ~e (e1 (e0 τ0 → e0 τ1) l e2 τ2 → a0) corresponding to a β- 4.2 Readback redex (λx.M) @ N in the untyped λ-term. Informally, each To show an exact correspondence with β-reduction, we portion of ∆¯ corresponds to a portion of the redex: τ0 to the define a readback function to reconstruct a pleasant skeleton type of x in M, τ1 to the result type of M, τ2 to the result from a typing and a constraint. type of N, and a0 to the result type of the whole redex. unify-β ~e (e1 (e0 τ0 → e0 τ1) l e2 τ2 → a0) −−−−−−→ ~e/((e2 := e1 e0 E, e1/e0/S); (a0 := [S] τ1, e1 := e0 := )) extract :=τ2 if τ0 −−−−→ E and τ0 −−−−→ S unify-@ ~e (e1 a0 l e2 τ1 → a0) −−−−−−→ ~e/(e1 := (a0 := e2 τ2 → a0, e1 := e1 e1 , e2 := e1 e2 ))

extract :=τ2 α −−−−→  α −−−−→ (α := τ2) extract extract extract :=τ2 :=τ2 :=τ2 τ1 ∩. τ2 −−−−→ E1 ∩. E2 if τ1 −−−−→ E1 and τ2 −−−−→ E2 τ1 ∩. τ2 −−−−→ S1; S2 if τ1 −−−−→ S1 and τ2 −−−−→ S2 :=τ2 :=τ2 e τ −extract−−−→ e E if τ −extract−−−→ E e τ −−−−→ e/S if τ −−−−→ S :=τ2 ω −extract−−−→ ω ω −−−−→ 

Figure 4: Rules for solving constraints.

Example 4.9 (Rule unify-β). Consider the following sin- no ~ei is a proper prefix of ~ej , with i, j ∈ {1, . . . , n}. This is gular constraint ∆¯ which is part of ∆ from example 4.1 (for guaranteed by the hypothesis constraint(P ) = ∆¯ ∩. ∆0, since memory, M = (λx.x @ x) @ y): for every i, ~ei is the E-path of some skeleton variable in P . Equalities of sec. 3.2 are imposed on types, but not on ∆¯ = (e (e e a ∩. e e a → e a ) l e a → a ) 0 0 00 1 0 1 0 0 2 0 0 0 2 0 0 expansions and substitutions, so E = E and S = S do 0 This constraint corresponds to the β-redex in M. We have not necessarily hold. However, all possible E and S have ¯ unify-β the same effect when they are applied to types. By defi- ∆ −−−−−→ S, where S is the following substitution: 0 nition 3.3, [S] ∆¯ = [S ] τ0 → [S] τ1 l [E] τ2 → [S] τ1. Since  .  0 00 0 e2 := e1 e0 (e1 ∩ e2 ) [E] τ2 = [E ] τ2 = [S ] τ0 = [S ] τ0, solved([S] ∆)¯ holds.   , e1 := e1 ( e0 := e0 ( e1 := e1 (a0 := a0 , ) , The next lemma shows that, given a pleasant skeleton   ; e2 := e2 (a0 := a0 , ) , ) P whose term is a β-redex, any substitution generated by , ) unify-β applied to the constraint ∆¯ of P generates a substi- ,  tution S that, when applied to P , (1) solves ∆¯ and only ∆,¯    ; a0 := a0 , e1 := e0 := , , (2) preserves definedness of readback, and (3) changes the term of the readback by contracting the β-redex considered. The first part of S (line 1, e2 := e1 e0 (e1  ∩. e2 )) makes as many copies of argument y of the β-redex as there are Lemma 4.11. Let M = (λx.M1) @ M2, let P = initial(M), 0 occurrences of the bound variable x. Each copy is put un- let constraint(P ) = ∆¯ ∩. ∆ , and let ∆¯ −−unify−−−-β−→ S. Then 0 0 0 derneath a distinct sequence of E-variables (here e1 and e2); readback([S] P ) = P where constraint(P ) = [S] ∆ and each sequence of E-variables corresponds to one occurrence 0 term(P ) = M1[x := M2]. of x. The second part of the substitution S (lines 2-4) re- places the type variable associated with each occurrence of The next two lemmas show the step-by-step equivalence the bound variable x with the result type of the correspond- between unify-β and β-reduction. ing copy of the argument y (this has no effect in this case, Lemma 4.12 (One step of unify-β corresponds to one because y also has type a0). The last part of S (line 6) si- step of β-reduction). If readback(Q) = P = initial(M), multaneously replaces the type variable that holds the result 0 M = term(P ), constraint(Q) w ∆˙ −−unify−−−-β−→ S, and Q = type of the application with the result type of the body of 0 0 0 0 [S] Q, then there exist M and P s.t. readback(Q ) = P = the λ-abstraction (having no effect in this case), and then 0 0 0 initial(M ), and M −−β−→ M = term(P ). erases E-variables e1 and e0. Only the E-variable e1 needs unify-β to be erased for the constraint to become solved; erasing e0 ∆˙ S is needed to preserve definedness of readback. constraint; w π1 0 0 Lemma 4.10. If constraint(P ) = ∆¯ ∩. ∆ and ∆¯ −−unify−−−-β−→ S, Q hS, Qi Q π2 [·] · then solved([S] ∆)¯ . readback readback 0 P P S π1 [·] ·; unsolved initial term initial term ¯ β 0 unify-β hS, ∆i ω M M π ∆¯ 2 Lemma 4.13 (One step of β-reduction corresponds unify readback initial The previous lemmas show that unify-β, when it applies to to one step of -β). If (Q) = P = (M), β 0 0 0 0 some constraint ∆¯ of a pleasant skeleton, produces a substi- term(P ) = M −−−→ M , initial(M ) = P , and term(P ) = 0 0 β ˙ ˙ tution S that solves ∆.¯ ∆¯ −−unify−−−- −→ S implies the following: M , then there exist ∆, S and Q s.t. constraint(Q) w ∆ unify-β 0 0 0 ∆¯ = e1 (e0 τ0 → e0 τ1) l e2 τ2 → a0 −−−−−−→ S, [S] Q = Q , and readback(Q ) = P . τ0 = ~e1 a0 ∩. · · · ∩. ~en a0 unify-β 0 ∆˙ S S = (e2 := e1 e0 E , e1/e0/S ) 0  constraint; w π1 ; (a0 := [S ] τ1 , e1 := e0 := ) 0 extract :=τ2 0 0 Q hS, Qi Q τ0 −−−−→ E and τ0 −−−→ S , for some E and S . π2 0 readback [·] · readback Let E = ~e1  ∩. · · · ∩. ~en  and 00 0 S = ~e1/(a0 := τ2); · · ·; ~en/(a0 := τ2). P P With these particular E0 and S00, it is easy to see that initial term initial term 0 00 β 0 [E ] τ2 = ~e1 τ2 ∩. · · · ∩. ~en τ2 = [S ] τ0 holds, provided that M M lo 4.3.2 Rule unify-@ M = C [(λx.M1) @ M2], in which case the occurrence of lo Rule unify-@ is designed to be used after rule unify-β the subterm (λx.M1) @ M2 in the hole of C is the left- has been used as much as possible and can not be used most/outermost redex of M. anymore. Because unify-β effectively simulates β-reduction, In order to precisely define the complete strategy for type this means when unify-β is done, the term resulting from inference, we now define the notions of leftmost/outermost readback is a β-normal form. Because a β-normal form may constraint, which we use for unify-β, and rightmost/innermost have applications in it, there may still be unsolved con- constraint, which we use for unify-@. straints. Rule unify-@ applies to singular constraints of the ¯ l form ∆ = e1 a0 e2 τ2 → a0. Such constraints are generated Definition 4.15 (Order on sequences of expansion by terms that are chains of applications whose head is a variables). Let ei < ej iff i < j. Thus, < is a strict total ¯ variable, i.e., terms of the form xM1 · · · Mn. For [S] ∆ to be order on expansion variables, and so is its lexicographic- solved, S must replace e1 a0 by an arrow type. extension order

A. FULL EXAMPLE OF TYPE INFERENCE (M . Q1) : hA1 ` τ1i / ∆1, where A (y) = e e e a ∩. e e e a This appendix shows an example of type inference, present- 1 1 0 2 0 2 0 2 0 τ = a ing output produced by our implementation, which has the 1 0 ∆1 = e1 (e0 e1 a0 → e0 a0) l e2 (e0 e1 a0 → e0 a0) → a0 option of writing bits of LATEX code suitable for inclusion in ∩. e1 (e0 e1 a0 → e0 a0) ∩. e2 (e0 e1 a0 → e0 a0) → a0 LATEX documents. We analyze the term M: l e1 (e0 e1 a0 → e0 a0) ∩. e2 (e0 e1 a0 → e0 a0) → a0 . l M = (λx.x @ x) @ (λz.z @ y) ∩ e1 e0 (e1 a0 e2 a0 → a0) ∩. e2 e0 (e1 a0 l e2 a0 → a0) For compactness, uses of result type subtyping which add The readback P1 of the judgement derived by Q1 is: a singular constraint that is solved have been omitted from skeletons in the rest of this section. However, these solved readback(A1, τ1, ∆1) = P1 = :a0 :a0 constraints are included in judgements. ( e1 (λx. e0 ((e1 (x ) : e2 a0 → a0) @ e2 (y ))) : e2 (e0 e1 a0 → e0 a0) → a0) :a0 :a0 A.1 Initial Skeleton @ e2 (λx. e0 ((e1 (x ) : e2 a0 → a0) @ e2 (y )))

The inference process starts by picking an initial skeleton The untyped term associated with P1 is: P0 = initial(M): term(P1) = (λx.x @ y) @ (λx.x @ y) :a0 :a0 P0 = ( e1 (λx. e0 ((e1 (x ) : e2 a0 → a0) @ e2 (x ))) β-LO Note that term(P0) −−−−−→ term(P1). : e2 (e0 e1 a0 → e0 a0) → a0) :a0 :a0 @ e2 (λz. e0 ((e1 (z ) : e2 a0 → a0) @ e2 (y ))) A.3 Step 2 (use of unify-β) The judgement P derives is: The leftmost-outermost unsolved constraint of Q1 to which 0 unify-β applies is:

(M . P0) : hA0 ` τ0i / ∆0, where ∆˙ 1 = e1 (e0 e1 a0 → e0 a0) l e2 (e0 e1 a0 → e0 a0) → a0 A0(y) = e2 e0 e2 a0 unify-β τ0 = a0 We have ∆˙ 1 −−−−−−→ S1 where: ∆0 = e1 (e0 e1 a0 ∩. e0 e2 a0 → e0 a0) S1 = e2 := e1 e0 e1  , e1/e0/e1/a0 := e0 e1 a0 → e0 a0 l e2 (e0 e1 a0 → e0 a0) → a0 ; a0 := a0 , e1 := e0 :=  ∩. e1 e0 (e1 a0 l e2 a0 → a0) ∩. e2 e0 (e1 a0 l e2 a0 → a0) The skeleton Q2 = [S1] Q1 is:

:e1 (e0 e1 a0→e0 a0)→a0 Q2 = (λx. (x ) The readback of the judgement derived by P0 is: :e0 e1 a0→e0 a0 @ e1 (x )) :e0 e1 a0→e0 a0 readback(A0, τ0, ∆0) = @ (λz. (e1 (z ) : e2 a0 → a0) :a0 :a0 :a0 ( e1 (λx. e0 ((e1 (x ) : e2 a0 → a0) @ e2 (x ))) @ e2 (y )) . :a0 :a0 : e2 (e0 e1 a0 → e0 a0) → a0) ∩ e1 (λz. e0 ((e1 (z ) : e2 a0 → a0) @ e2 (y ))) :a0 :a0 @ e2 (λx. e0 ((e1 (x ) : e2 a0 → a0) @ e2 (y )))

Note that, since we have quotiented skeletons and terms by The judgement Q2 derives is: α-equivalence (renaming of bound variables), this skeleton (M . Q2) : hA2 ` τ2i / ∆2, where is actually equal to P0. Of course, term(P0) = M. A2(y) = e2 a0 ∩. e1 e0 e2 a0 τ2 = a0 A.2 Step 1 (use of unify-β) ∆2 = e1 (e0 e1 a0 → e0 a0) → a0 l The leftmost-outermost unsolved constraint of Q to which e1 (e0 e1 a0 → e0 a0) → a0 0 . unify-β applies is: ∩ (e1 (e0 e1 a0 → e0 a0) → a0) ∩. e1 (e0 e1 a0 → e0 a0) ∆˙ 0 = e1 (e0 e1 a0 ∩. e0 e2 a0 → e0 a0)le2 (e0 e1 a0 → e0 a0) → a0 → a0 l (e1 (e0 e1 a0 → e0 a0) → a0) unify-β . We have ∆˙ 0 −−−−−→ S0 where: ∩ e1 (e0 e1 a0 → e0 a0) → a0  .  S0 = e2 := e1 e0 (e1 ∩ e2 ) ∩. e1 (e0 e1 a0 → e0 a0) l e2 a0 → a0 , e1/e0/ e1/a0 := e0 e1 a0 → e0 a0 ∩. e1 e0 (e1 a0 l e2 a0 → a0) ; e2/a0 := e0 e1 a0 → e0 a0 The readback P2 of the judgement derived by Q2 is: ; a0 := a0 , e1 := e0 :=  readback(A2, τ2, ∆2) = P2 = :a0 :a0 The skeleton Q1 = [S0] Q0 is: ( e1 (λx. e0 ((e1 (x ) : e2 a0 → a0) @ e2 (y ))) e a a :e0 e1 a0→e0 a0 : 2 0 → 0) Q1 = (λx. ( e1 (x ) :a0 @ e2 (y ) : e2 (e0 e1 a0 → e0 a0) → a0) :e0 e1 a0→e0 a0 @ e2 (x )) The untyped term associated with P2 is: :a0 :a0 @ e1 (λz. e0 ((e1 (z ) : e2 a0 → a0) @ e2 (y ))) term :a0 :a0 (P2) = (λx.x @ y) @ y ∩. e2 (λz. e0 ((e1 (z ) : e2 a0 → a0) @ e2 (y ))) β-LO Note that term(P1) −−−−−→ term(P2). The following diagram sums up the relations between the entities presented in appendix A. The path followed by type inference is drawn in solid lines, and the β-reduction sequence it implies is drawn in dashed lines. The relation β-LO is the least such that lo β-LO lo 0 [S] · 0 0 C [(λx.M1) @ M2] −−−−−→ C [M1[x := M2]], readback is given in appendix B, and X −−−→ X means X = [S] X.

initial M M1 M2 Mnf β-LO β-LO β-LO input initial term initial term initial term term

initial term P1 P2 P3 P4 0 readback readback readback readback [S0] · [S1] · [S2] · [S3] · readback P0 Q1 Q2 Q3 Q4 constraint constraint constraint constraint constraint [S0] · [S1] · [S2] · [S3] · ∆0 ∆1 ∆2 ∆3 ∆4 ω unsolved filter-β; LO filter-β; LO filter-β; LO unsolved; RI unify-β unify-β unify-β unify-@ ∆˙ 0 S0 ∆˙ 1 S1 ∆˙ 2 S2 ∆˙ 3 S3 π2 π2 π2 π1 final · ; · 0 π1 0 · ; · 0 π1 0 · ; · hS0, S1i S1 hS1, S2i S2 hS2, S3i S result

Figure 5: Outline of example of type inference.

unify-@ A.4 Step 3 (use of unify-β) We have ∆˙ 3 −−−−−−→ S3 where:

The leftmost-outermost unsolved constraint of Q2 to which S3 = e1 := a0 := e2 a0 → a0 , e1 := e1 e1  , e2 := e1 e2  unify-β applies is: The skeleton Q4 = [S3] Q3 is: ∆˙ = e (e e a → e a ) l e a → a 2 1 0 1 0 0 0 2 0 0 :((e2 a0→a0)→a0)→a0 :(e2 a0→a0)→a0 Q4 = (λx. (x ) @ (x )) unify-β :(e2 a0→a0)→a0 :e2 a0→a0 We have ∆˙ 2 −−−−−→ S2 where: @ (λz. (z ) @ (y )) :e2 a0→a0 :a0 ∩. (λz. (z ) @ e2 (y )) S2 = e2 := e1 e0 e1  , e1/e0/e1/a0 := a0 ; a0 := a0 , e1 := e0 :=  The judgement Q4 derives is: The skeleton Q3 = [S2] Q2 is: (M . Q4) : hA4 ` τ4i / ∆4, where :(e1 a0→a0)→a0 :e1 a0→a0 . Q3 = (λx. (x ) @ (x )) A4(y) = (e2 a0 → a0) ∩ e2 a0 :e1 a0→a0 :a0 @ (λz. (z ) @ e1 (y )) τ4 = a0 :a0 :a0 ∩. (λz. (e1 (z ) : e2 a0 → a0) @ e2 (y )) ∆4 = ((e2 a0 → a0) → a0) → a0 l ((e2 a0 → a0) → a0) → a0 The judgement Q3 derives is: ∩. (((e2 a0 → a0) → a0) → a0) ∩. ((e2 a0 → a0) → a0) (M . Q3) : hA3 ` τ3i / ∆3, where → a0 A3(y) = e1 a0 ∩. e2 a0 l (((e2 a0 → a0) → a0) → a0) τ3 = a0 ∩. ((e2 a0 → a0) → a0) ∆3 = (e1 a0 → a0) → a0 l (e1 a0 → a0) → a0 → a0 ∩. ((e1 a0 → a0) → a0) ∩. (e1 a0 → a0) → a0 ∩. (e2 a0 → a0) → a0 l (e2 a0 → a0) → a0 l ((e1 a0 → a0) → a0) ∩. (e1 a0 → a0) → a0 ∩. e2 a0 → a0 l e2 a0 → a0 ∩. e1 a0 → a0 l e1 a0 → a0 ∩. e1 a0 l e2 a0 → a0 Note that Q4 is solved. By lem. 3.5, the substitution S = S0; S1; S2; S3 solves the initial skeleton P0. The readback P3 of the judgement derived by Q3 is:

:a0 :a0 readback(A3, τ3, ∆3) = P3 = (e1 (y ) : e2 a0 → a0) @ e2 (y ) B. IMPROVED READBACK A slight modification to readback, which we have imple- The untyped term associated with P3 is: mented, allows it to operate after unify-@ has been used. We present this variation because it may be of interest, and also term(P3) = y @ y because it is mentioned by the full example (appendix A). β-LO Note that term(P2) −−−−−→ term(P3), and term(P3) is a β- The first case of the definition of readback is modified thus: normal form. readback(A, a0, ω) :τ = x @ Q1 @ · · · @ Qn unify A.5 Step 4 (use of -@) if A = ~e1 e2 A1 ∩. · · · ∩. ~en e2 An ∩. (x : τ) At this step, Q3 has no singular constraint to which unify-@ and τ = ~e1 e2 τ1 → · · · → ~en e2 τn → a0 applies, so we switch to using unify-@ in order to solve the and Q1 = ~e1 e2 readback(A1, τ1, ω) remaining constraints. The rightmost-innermost unsolved · · · constraint of Q3 is: Qn = ~en e2 readback(An, τn, ω)

∆˙ 3 = e1 a0 l e2 a0 → a0 where ~en =  and if 1 ≤ i < n then ~ei = e1 · ~ei+1.