ConSORT: Context- and Flow-Sensitive Ownership Refinement Types for Imperative Programs
John Toman, Ren Siqi, Kohei Suenaga, Atsushi Igarashi, Naoki Kobayashi
CConSORT: Context- and Flow-SensitiveOwnership Refinement Types for ImperativePrograms
John Toman , Ren Siqi , Kohei Suenaga ,Atsushi Igarashi , and Naoki Kobayashi Kyoto University, Kyoto, Japan, { jtoman,shiki,ksuenaga,igarashi } @fos.kuis.kyoto-u.ac.jp The University of Tokyo, Tokyo, Japan, [email protected]
Abstract.
We present
ConSORT , a type system for safety verificationin the presence of mutability and aliasing. Mutability requires strongupdates to model changing invariants during program execution, butaliasing between pointers makes it difficult to determine which invariantsmust be updated in response to mutation. Our type system addressesthis difficulty with a novel combination of refinement types and fractionalownership types. Fractional ownership types provide flow-sensitive andprecise aliasing information for reference variables.
ConSORT interpretsthis ownership information to soundly handle strong updates of potentiallyaliased references. We have proved
ConSORT sound and implemented aprototype, fully automated inference tool. We evaluated our tool and foundit verifies non-trivial programs including data structure implementations.
Keywords: refinement types, mutable references, aliasing, strong up-dates, fractional ownerships, program verification, type systems
Driven by the increasing power of automated theorem provers and recent high-profile software failures, fully automated program verification has seen a surgeof interest in recent years [5, 10, 15, 29, 38, 65]. In particular, refinement types [9, 21, 24, 64], which refine base types with logical predicates, have been shown tobe a practical approach for program verification that are amenable to (sometimesfull) automation [47, 60, 61, 62]. Despite promising advances [26, 32, 46], the soundand precise application of refinement types (and program verification in general)in settings with mutability and aliasing (e.g., Java, Ruby, etc.) remains difficult.One of the major challenges is how to precisely and soundly support strongupdates for the invariants on memory cells. In a setting with mutability, a singleinvariant may not necessarily hold throughout the lifetime of a memory cell; whilethe program mutates the memory the invariant may change or evolve. To modelthese changes, a program verifier must support different, incompatible invariantswhich hold at different points during program execution. Further, precise programverification requires supporting different invariants on distinct pieces of memory. a r X i v : . [ c s . P L ] F e b J. Toman et al. mk(n) { mkref n } let p = mk(3) in let q = mk(5) in p := *p + 1; q := *q + 1; assert (*p = 4); Fig. 1.
Example demonstrating the dif-ficulty of effecting strong updates in thepresence of aliasing. The function mk isbound in the program from lines 3 to 7;its body is given within the braces. loop(a, b) { let aold = *a in b := *b + 1; a := *a + 1; assert (*a = aold + 1); if (cid:63) then loop(b, mkref (cid:63) ) else loop(b,a) } loop( mkref (cid:63) , mkref (cid:63) ) Fig. 2.
Example with non-trivial alias-ing behavior.
One solution is to use refinement types on the static program names (i.e.,variables) which point to a memory location. This approach can model evolvinginvariants while tracking distinct invariants for each memory cell. For example,consider the (contrived) example in Figure 1. This program is written in an ML-like language with mutable references; references are updated with := and allo-cated with mkref . Variable p can initially be given the type { ν : int | ν = 3 } ref ,indicating it is a reference to the integer 3. Similarly, q can be given the type { ν : int | ν = 5 } ref . We can model the mutation of p ’s memory on line 5 bystrongly updating p ’s type to { ν : int | ν = 4 } ref .Unfortunately, the precise application of this technique is confounded by theexistence of unrestricted aliasing. In general, updating just the type of the mutatedreference is insufficient: due to aliasing, other variables may point to the mutatedmemory and their refinements must be updated as well. However, in the presenceof conditional, may aliasing, it is impossible to strongly update the refinements onall possible aliases; given the static uncertainty about whether a variable points tothe mutated memory, that variable’s refinement may only be weakly updated . Forexample, suppose we used a simple alias analysis that imprecisely (but soundly)concluded all references allocated at the same program point might alias. Variables p and q share the allocation site on line 1, so on line 5 we would have to weaklyupdate q ’s type to { ν : int | ν = 4 ∨ ν = 5 } , indicating it may hold either 4 or
5. Under this same imprecise aliasing assumption, we would also have to weaklyupdate p ’s type on line 6, preventing the verification of the example program.Given the precision loss associated with weak updates, it is critical thatverification techniques built upon refinement types use precise aliasing informationand avoid spuriously applied weak updates. Although it is relatively simple toconclude that p and q do not alias in Figure 1, consider the example in Figure 2.(In this example, (cid:63) represents non-deterministic values.) Verifying this programrequires proving a and b never alias at the writes on lines 3 and 4. In fact, a and b may point to the same memory location, but only in different invocationsof loop ; this pattern may confound even sophisticated symbolic alias analyses. onSORT : Context- and Flow-Sensitive Ownership Refinement Types 3 Additionally, a and b share an allocation site on line 7, so an approach based onthe simple alias analysis described above will also fail on this example. This must-not alias proof obligation can be discharged with existing techniques [53, 54], butrequires an expensive, on-demand, interprocedural, flow-sensitive alias analysis.This paper presents ConSORT (CONtext Sensitive Ownership RefinementTypes), a type system for the automated verification of program safety in imper-ative languages with mutability and aliasing.
ConSORT is built upon the novelcombination of refinement types and fractional ownership types [55, 56]. Frac-tional ownership types extend pointer types with a rational number in the range[0 ,
1] called an ownership . These ownerships encapsulate the permission of thereference; only references with ownership 1 may be used for mutation. Fractionalownership types also obey the following key invariant: any references with a mu-table alias must have ownership 0. Thus, any reference with non-zero ownership cannot be an alias of a reference with ownership 1. In other words, ownershipsencode precise aliasing information in the form of must-not aliasing relationships.To understand the benefit of this approach, let us return to Figure 1. As mk returns a freshly allocated reference with no aliases, its type indicates it returns areference with ownership 1. Thus, our type system can initially give p and q types { ν : int | ν = 3 } ref and { ν : int | ν = 5 } ref respectively. The ownership 1 onthe reference type constructor ref indicates both pointers hold “exclusive” own-ership of the pointed to reference cell; from the invariant of fractional ownershiptypes p and q must not alias. The types of both references can be strongly up-dated without requiring spurious weak updates. As a result, at the assertion state-ment on line 7, p has type { ν : int | ν = 4 } ref expressing the required invariant.Our type system can also verify the example in Figure 2 without expensiveside analyses. As a and b are both mutated, they must both have ownership 1;i.e., they cannot alias. This pre-condition is satisfied by all invocations of loop ;on line 7, b has ownership 1 (from the argument type), and the newly allocatedreference must also have ownership 1. Similarly, both arguments on line 9 haveownership 1 (from the assumed ownership on the argument types).Ownerships behave linearly; they cannot be duplicated, only split when aliasesare created. This linear behavior preserves the critical ownership invariant. Forexample, if we replace line 9 in Figure 2 with loop(b,b) , the program becomesill-typed; there is no way to divide b ’s ownership of 1 to into two ownerships of 1.Ownerships also obviate updating refinement information of aliases at muta-tion. ConSORT ensures that only the trivial refinement (cid:62) is used in referencetypes with ownership 0, i.e., mutably-aliased references. When memory is mu-tated through a reference with ownership 1,
ConSORT simply updates the refine-ment of the mutated reference variable. From the soundness of ownership types,all aliases have ownership 0 and must therefore only contain the (cid:62) refinement.Thus, the types of all aliases already soundly describe all possible contents. ConSORT is also context-sensitive , and can use different summaries of func-tion behavior at different points in the program. For example, consider the variant This assumption holds only if updates do not change simple types, a condition ourtype-system enforces. J. Toman et al. get(p) { *p } let p = mkref in let q = mkref in p := get(p) + 1; q := get(q) + 1; assert (*p = 4); assert (*q = 6); Fig. 3.
Example ofcontext-sensitivity of Figure 1 shown in Figure 3. The function get returnsthe contents of its argument, and is called on lines 5and 6. To precisely verify this program, on line 5 get must be typed as a function that takes a reference to3 and returns 3. Similarly, on line 6 get must be typedas a function that takes a reference to 5 and returns5. Our type system can give get a function type thatdistinguishes between these two calling contexts andselects the appropriate summary of get ’s behavior.We have formalized
ConSORT as a type systemfor a small imperative calculus and proved the systemis sound: i.e., a well-typed program never encounters as-sertion failures during execution. We have implementeda prototype type inference tool targeting this impera-tive language and found it can automatically verify several non-trivial programs,including sorted lists and an array list data structure.The rest of this paper is organized as follows. Section 2 defines the imperativelanguage targeted by
ConSORT and its semantics. Section 3 defines our typesystem and states our soundness theorem. Section 4 sketches our implementa-tion’s inference algorithm and its current limitations. Section 5 describes an eval-uation of our prototype, Section 6 outlines related work, and Section 7 concludes.
This section describes a simple imperative language with mutable references andfirst-order, recursive functions.
We assume a set of variables , ranged over by x, y, z, . . . , a set of function names ,ranged over by f , and a set of labels , ranged over by (cid:96) , (cid:96) , . . . . The grammar ofthe language is as follows. d ::= f (cid:55)→ ( x , ... , x n ) ee ::= x | let x = y in e | let x = n in e | ifz x then e else e | let x = mkref y in e | let x = ∗ y in e | let x = f (cid:96) ( y , . . . , y n ) in e | x : = y ; e | alias ( x = y ) ; e | alias ( x = ∗ y ) ; e | assert ( ϕ ) ; e | e ; e P ::= (cid:104){ d , ... , d n } , e (cid:105) ϕ stands for a formula in propositional first-order logic over variables, integersand contexts; we discuss these formulas later in Section 3.1.Variables are introduced by function parameters or let bindings. Like ML, thevariable bindings introduced by let expressions and parameters are immutable.Mutable variable declarations such as int x = 1; in C are achieved in our lan-guage with: let y = 1 in ( let x = mkref y in . . . ) . onSORT : Context- and Flow-Sensitive Ownership Refinement Types 5 As a convenience, we assume all variable names introduced with let bindings andfunction parameters are distinct.Unlike ML (and like C or Java) we do not allow general expressions on theright hand side of let bindings. The simplest right hand forms are a variable y oran integer literal n . mkref y creates a reference cell with value y , and ∗ y accessesthe contents of reference y . For simplicity, we do not include an explicit null value;an extension to support null is discussed in Section 4. Function calls must occuron the right hand side of a variable binding and take the form f (cid:96) ( x , . . . , x n ),where x , . . . , x n are distinct variables and (cid:96) is a (unique) label. These labels areused to make our type system context-sensitive as discussed in Section 3.3.The single base case for expressions is a single variable. If the variableexpression is executed in a tail position of a function, then the value of thatvariable is the return value of the function, otherwise the value is ignored.The only intraprocedural control-flow operations in our language are if state-ments. ifz checks whether the condition variable x equals zero and chooses thecorresponding branch. Loops can be implemented with recursive functions andwe do not include them explicitly in our formalism.Our grammar requires that side-effecting, result-free statements, assert ( ϕ ) alias ( x = y ), alias ( x = ∗ y ) and assignment x := y are followed by a continu-ation expression. We impose this requirement for technical reasons to ease ourformal presentation; this requirement does not reduce expressiveness as dummycontinuations can be inserted as needed. The assert ( ϕ ) ; e form executes e ifthe predicate ϕ holds in the current state and aborts the program otherwise. alias ( x = y ) ; e and alias ( x = ∗ y ) ; e assert a must-aliasing relationship between x and y (resp. x and ∗ y ) and then execute e . alias statements are effectively an-notations that our type system exploits to gain added precision. x : = y ; e updatesthe contents of the memory cell pointed to by x with the value of y . In additionto the above continuations, our language supports general sequencing with e ; e .A program is a pair (cid:104) D , e (cid:105) , where D = { d , ... , d n } is a set of first-order,mutually recursive function definitions, and e is the program entry point. Afunction definition d maps the function name to a tuple of argument names x , ... , x n that are bound within the function body e . Paper Syntax.
In the remainder of the paper, we will write programs that aretechnically illegal according to our grammar, but can be easily “de-sugared” intoan equivalent, valid program. For example, we will write let x = mkref in assert (*x = 4) as syntactic sugar for: let f = 4 in let x = mkref f inlet tmp = *x in assert (tmp = 4); let dummy = 0 in dummy We now introduce the operational semantics for our language. We assume afinite domain of heap addresses
Addr : we denote an arbitrary address with a . J. Toman et al. (cid:68) H , R , F : (cid:126)F , x (cid:69) −→ D (cid:68) H , R , (cid:126)F , F [ x ] (cid:69) ( R-Var ) (cid:68) H , R , F : (cid:126)F , E [ x ; e ] (cid:69) −→ D (cid:68) H , R , (cid:126)F , E [ e ] (cid:69) ( R-Seq ) x (cid:48) (cid:54)∈ dom ( R ) (cid:68) H , R , (cid:126)F , E [ let x = y in e ] (cid:69) −→ D (cid:68) H , R { x (cid:48) (cid:55)→ R ( y ) } , (cid:126)F , E [[ x (cid:48) / x ] e ] (cid:69) ( R-Let ) x (cid:48) (cid:54)∈ dom ( R ) (cid:68) H , R , (cid:126)F , E [ let x = n in e ] (cid:69) −→ D (cid:68) H , R { x (cid:48) (cid:55)→ n } , (cid:126)F , E [[ x (cid:48) / x ] e ] (cid:69) ( R-LetInt ) R ( x ) = 0 (cid:68) H , R , (cid:126)F , E [ ifz x then e else e ] (cid:69) −→ D (cid:68) H , R , (cid:126)F , E [ e ] (cid:69) ( R-IfTrue ) R ( x ) (cid:54) = 0 (cid:68) H , R , (cid:126)F , E [ ifz x then e else e ] (cid:69) −→ D (cid:68) H , R , (cid:126)F , E [ e ] (cid:69) ( R-IfFalse ) a (cid:54)∈ dom ( H ) x (cid:48) (cid:54)∈ dom ( R ) (cid:68) H , R , (cid:126)F , E [ let x = mkref y in e ] (cid:69) −→ D (cid:68) H { a (cid:55)→ R ( y ) } , R { x (cid:48) (cid:55)→ a } , (cid:126)F , E [[ x (cid:48) / x ] e ] (cid:69) ( R-MkRef ) R ( y ) = a H ( a ) = v x (cid:48) (cid:54)∈ dom ( R ) (cid:68) H , R , (cid:126)F , E [ let x = ∗ y in e ] (cid:69) −→ D (cid:68) H , R { x (cid:48) (cid:55)→ v } , (cid:126)F , E [[ x (cid:48) / x ] e ] (cid:69) ( R-Deref ) Fig. 4.
Transition Rules (1).
A runtime state is represented by a configuration (cid:68) H , R , (cid:126)F , e (cid:69) , which consistsof a heap, register file, stack, and currently reducing expression respectively.The register file maps variables to runtime values v , which are either integers n or addresses a . The heap maps a finite subset of addresses to runtime values.The runtime stack represents pending function calls as a sequence of returncontexts, which we describe below. While the final configuration component is anexpression, the rewriting rules are defined in terms of E [ e ], which is an evaluationcontext E and redex e , as is standard. The grammar for evaluation contexts isdefined by: E ::= E (cid:48) ; e | [] . Our operational semantics is given in Figures 4 and 5. We write dom ( H ) toindicate the domain of a function and H { a (cid:55)→ v } where a (cid:54)∈ dom ( H ) to denote amap which takes all values in dom ( H ) to their values in H and which additionallytakes a to v . We will write H { a ← (cid:45) v } where a ∈ dom ( H ) to denote a mapequivalent to H except that a takes value v . We use similar notation for dom ( R )and R { x (cid:55)→ v } . We also write ∅ for the empty register file and heap. The steprelation −→ D is parameterized by a set of function definitions D ; a program (cid:104) D , e (cid:105) is executed by stepping the initial configuration (cid:104)∅ , ∅ , · , e (cid:105) according to −→ D .The semantics is mostly standard; we highlight some important points below.Return contexts F take the form E [ let y = [] (cid:96) in e ]. A return context repre-sents a pending function call with label (cid:96) , and indicates that y should be bound tothe return value of the callee during the execution of e within the larger executioncontext E . The call stack (cid:126)F is a sequence of these contexts, with the first such re-turn context representing the most recent function call. The stack grows at func-tion calls as described by rule R-Call . For a call E [ let x = f (cid:96) ( y , . . . , y n ) in e ]where f is defined as ( x , ... , x n ) e (cid:48) , the return context E [ let y = [] (cid:96) in e ] is onSORT : Context- and Flow-Sensitive Ownership Refinement Types 7 f (cid:55)→ ( x , .. , x n ) e ∈ D (cid:68) H , R , (cid:126)F , E [ let x = f (cid:96) ( y , . . . , y n ) in e (cid:48) ] (cid:69) −→ D (cid:68) H , R , E [ let x = [] (cid:96) in e (cid:48) ] : (cid:126)F , [ y / x ] · · · [ y n / x n ] e (cid:69) ( R-Call ) R ( x ) = a a ∈ dom ( H ) (cid:68) H , R , (cid:126)F , E [ x : = y ; e ] (cid:69) −→ D (cid:68) H { a ← (cid:45) R ( y ) } , R , (cid:126)F , E [ e ] (cid:69) ( R-Assign ) R ( x ) = R ( y ) (cid:68) H , R , (cid:126)F , E [ alias ( x = y ) ; e ] (cid:69) −→ D (cid:68) H , R , (cid:126)F , E [ e ] (cid:69) ( R-Alias ) R ( y ) = a H ( a ) = R ( x ) (cid:68) H , R , (cid:126)F , E [ alias ( x = ∗ y ) ; e ] (cid:69) −→ D (cid:68) H , R , (cid:126)F , E [ e ] (cid:69) ( R-AliasPtr ) R ( x ) (cid:54) = R ( y ) (cid:68) H , R , (cid:126)F , E [ alias ( x = y ) ; e ] (cid:69) −→ D AliasFail ( R-AliasFail ) R ( x ) (cid:54) = H ( R ( y )) (cid:68) H , R , (cid:126)F , E [ alias ( x = ∗ y ) ; e ] (cid:69) −→ D AliasFail ( R-AliasPtrFail ) | = [ R ] ϕ (cid:68) H , R , (cid:126)F , E [ assert ( ϕ ) ; e ] (cid:69) −→ D (cid:68) H , R , (cid:126)F , E [ e ] (cid:69) ( R-Assert ) (cid:54)| = [ R ] ϕ (cid:68) H , R , (cid:126)F , E [ assert ( ϕ ) ; e ] (cid:69) −→ D AssertFail ( R-AssertFail ) Fig. 5.
Transition Rules (2). prepended onto the stack of the input configuration. The substitution of formalarguments for parameters in e (cid:48) , denoted by [ y / x ] · · · [ y n / x n ] e (cid:48) , becomes thecurrently reducing expression in the output configuration. Function returns arehandled by R-Var . Our semantics return values by name; when the currentlyexecuting function fully reduces to a single variable x , x is substituted into thereturn context on the top of the stack, denoted by E [ let y = [] (cid:96) in e ][ x ].In the rules R-Assert we write | = [ R ] ϕ to mean that the formula yieldedby substituting the concrete values in R for the variables in ϕ is valid withinsome chosen logic (see Section 3.1); in R-AssertFail we write (cid:54)| = [ R ] ϕ whenthe formula is not valid. The substitution operation [ R ] ϕ is defined inductivelyas [ ∅ ] ϕ = ϕ, [ R { x (cid:55)→ n } ] ϕ = [ R ] [ n/ x ] ϕ, [ R { x (cid:55)→ a } ] ϕ = [ R ] ϕ . In the case of anassertion failure, the semantics steps to a distinguished configuration AssertFail .The goal of our type system is to show that no execution of a well-typed programmay reach this configuration. The alias form checks whether the two referencesactually alias; i.e., if the must-alias assertion provided by the programmer iscorrect. If not, our semantics steps to the distinguished
AliasFail configuration.Our type system does not guarantee that
AliasFail is unreachable; aliasingassertions are effectively trusted annotations that are assumed to hold.In order to avoid duplicate variable names in our register file due to recursivefunctions, we refresh the bound variable x in a let expression to x (cid:48) . Take expression let x = y in e as an example; we substitute a fresh variable x (cid:48) for x in e , then bind x (cid:48) to the value of variable y . We assume this refreshing of variables preserves ourassumption that all variable bindings introduced with let and function parametersare unique, i.e. x (cid:48) does not overlap with variable names that occur in the program. J. Toman et al.
Types τ ::= { ν : int | ϕ } | τ ref r Ownership r ∈ [0 , Refinements ϕ ::= ϕ ∨ ϕ | ¬ ϕ | (cid:62)| φ ( (cid:98) v , .. , (cid:98) v n ) | (cid:98) v = (cid:98) v | CP Ref. Values (cid:98) v ::= x | n | ν Function Types σ ::= ∀ λ. (cid:104) x : τ , . . . , x n : τ n (cid:105)→ (cid:104) x : τ (cid:48) , . . . , x n : τ (cid:48) n | τ (cid:105) Context Variables λ ∈ CVar
Concrete Context (cid:126)(cid:96) ::= (cid:96) : (cid:126)(cid:96) | (cid:15) Pred. Context C ::= (cid:96) : C | λ | (cid:15) Context Query CP ::= (cid:126)(cid:96) (cid:22) C Typing Context L ::= λ | (cid:126)(cid:96) Fig. 6.
Syntax of types, refinements, and contexts.
We now introduce a fractional ownership refinement type system that guaranteeswell-typed programs do not encounter assertion failures.
The syntax of types is given in Figure 6. Our type system has two type con-structors: references and integers. τ ref r is the type of a (non-null) reference to avalue of type τ . r is an ownership which is a rational number in the range [0 , ConSORT ensures that these invariantshold while aliases are created and destroyed during execution.Integers are refined with a predicate ϕ . The language of predicates is built usingthe standard logical connectives of first-order logic, with (in)equality betweenvariables and integers, and atomic predicate symbols φ as the basic atoms. Weinclude a special “value” variable ν representing the value being refined by thepredicate. For simplicity, we omit the connectives ϕ ∧ ϕ and ϕ = ⇒ ϕ ; theycan be written as derived forms using the given connectives. We do not fix aparticular theory from which φ are drawn, provided a sound (but not necessarilycomplete) decision procedure exists. CP are context predicates, which are usedfor context sensitivity as explained below. Example 1. { ν : int | ν > } is the type of strictly positive integers. The typeof immutable references to integers exactly equal to 3 can be expressed by { ν : int | ν = 3 } ref . .As is standard, we denote a type environment with Γ , which is a finite mapfrom variable names to type τ . We write Γ [ x : τ ] to denote a type environment Γ such that Γ ( x ) = τ where x ∈ dom ( Γ ), Γ, x : τ to indicate the extension of Γ with the type binding x : τ , and Γ [ x ← (cid:45) τ ] to indicate the type environment Γ with the binding of x updated to τ . We write the empty environment as onSORT : Context- and Flow-Sensitive Ownership Refinement Types 9 • . The treatment of type environments as mappings instead of sequences in adependent type system is somewhat non-standard. The standard formulationbased on ordered sequences of bindings and its corresponding well-formednesscondition did not easily admit variables with mutually dependent refinementsas introduced by our function types (see below). We therefore use an unorderedenvironment and relax well-formedness to ignore variable binding order. Function Types, Contexts, and Context Polymorphism.
Our type system achievescontext sensitivity by allowing function types to depend on where a function iscalled, i.e., the execution context of the function invocation. Our system representsa concrete execution contexts with strings of call site labels (or just “call strings”),defined by (cid:126)(cid:96) ::= (cid:15) | (cid:96) : (cid:126)(cid:96) . As is standard (e.g., [49, 50]), the string (cid:96) : (cid:126)(cid:96) abstracts anexecution context where the most recent, active function call occurred at call site (cid:96) which itself was executed in a context abstracted by (cid:126)(cid:96) ; (cid:15) is the context underwhich program execution begins. Context variables , drawn from a finite domain
CVar and ranged over by λ , λ , . . . , represent arbitrary, unknown contexts.A function type takes the form ∀ λ. (cid:104) x : τ , . . . , x n : τ n (cid:105) → (cid:104) x : τ (cid:48) , . . . , x n : τ (cid:48) n | τ (cid:105) .The arguments of a function are an n -ary tuple of types τ i . To model side-effects onarguments, the function type includes the same number of output types τ (cid:48) i . In ad-dition, function types have a direct return type τ . The argument and output typesare given names: refinements within the function type may refer to these names.Function types in our language are context polymorphic, expressed by universalquantification “ ∀ λ. ” over a context variable. Intuitively, this context variable repre-sents the many different execution contexts under which a function may be called.Argument and return types may depend on this context variable by including context query predicates in their refinements. A context query predicate CP usually takes the form (cid:126)(cid:96) (cid:22) λ , and is true iff (cid:126)(cid:96) is a prefix of the concrete contextrepresented by λ . Intuitively, a refinement (cid:126)(cid:96) (cid:22) λ = ⇒ ϕ states that ϕ holds in anyconcrete execution context with prefix (cid:126)(cid:96) , and provides no information in any othercontext. In full generality, a context query predicate may be of the form (cid:126)(cid:96) (cid:22) (cid:126)(cid:96) or (cid:126)(cid:96) (cid:22) (cid:96) . . . (cid:96) n : λ ; these forms may be immediately simplified to (cid:62) , ⊥ or (cid:126)(cid:96) (cid:48) (cid:22) λ . Example 2.
The type { ν : int | ( (cid:96) (cid:22) λ = ⇒ ν = 3) ∧ ( (cid:96) (cid:22) λ = ⇒ ν = 5) } rep-resents an integer that is 3 if the most recent active function call site is (cid:96) , 5 ifthe most recent call site is (cid:96) , and is otherwise unconstrained. This type may beused for the argument of f in, e.g., f (cid:96) (3) + f (cid:96) (5) .As types in our type system may contain context variables, our typingjudgment (introduced below) includes a typing context L , which is either asingle context variable λ or a concrete context (cid:126)(cid:96) . This typing context representsthe assumptions about the execution context of the term being typed. If thetyping context is a context variable λ , then no assumptions are made about theexecution context of the term, although types may depend upon λ with contextquery predicates. Accordingly, function bodies are typed under the contextvariable universally quantified over in the corresponding function type; i.e., noassumptions are made about the exact execution context of the function body. As in parametric polymorphism, consistent substitution of a concrete context (cid:126)(cid:96) for a context variable λ in a typing derivation yields a valid type derivationunder concrete context (cid:126)(cid:96) . Remark 1.
The context-sensitivity scheme described here corresponds to thestandard CFA approach [50] without a priori call-string limiting. We chose thisscheme because it can be easily encoded with equality over integer variables (seeSection 4), but in principle another context-sensitivity strategy could be usedinstead. The important feature of our type system is the inclusion of predicatesover contexts, not the specific choice for these predicates.Function type environments are denoted with Θ and are finite maps fromfunction names ( f ) to function types ( σ ). Well Formedness.
We impose two well-formedness conditions on types: ownershipwell-formedness and refinement well-formedness . The ownership condition ispurely syntactic: τ is ownership well-formed if τ = τ (cid:48) ref implies τ (cid:48) = (cid:62) n forsome n . (cid:62) i is the “maximal” type of a chain of i references, and is definedinductively as (cid:62) = { ν : int | (cid:62)} , (cid:62) i = (cid:62) i − ref .The ownership well-formedness condition ensures that aliases introduced viaheap writes do not violate the invariant of ownership types and that refinementsare consistent with updates performed through mutable aliases. Recall our own-ership type invariant ensures all aliases of a mutable reference have 0 ownership.Any mutations through that mutable alias will therefore be consistent with the“no information” (cid:62) refinement required by this well-formedness condition.Refinement well-formedness, denoted L | Γ (cid:96) WF ϕ , ensures that free programvariables in refinement ϕ are bound in a type environment Γ and have integer type.It also requires that for a typing context L = λ , only context query predicatesover λ are used (no such predicates may be used if L = (cid:126)(cid:96) ). Notice this conditionforbids refinements that refer to references. Although ownership information cansignal when refinements on a mutably-aliased reference must be discarded, ourcurrent formulation provides no such information for refinements that mention mutably-aliased references. We therefore conservatively reject such refinementsat the cost of some expressiveness in our type system.We write L | Γ (cid:96) WF τ to indicate a well-formed type where all refinements arewell-formed with respect to L and Γ . We write L (cid:96) WF Γ for a type environmentwhere all types are well-formed. A function environment is well-formed (written (cid:96) WF Θ ) if, for every σ in Θ , the argument, result, and output types are well-formed with respect to each other and the context variable quantified over in σ .As the formal definition of refinement well-formedness is fairly standard, we omitit for space reasons (the full definition may be found in Appendix B). We now introduce the type system for the intraprocedural fragment of ourlanguage. Accordingly, this section focuses on the interplay of mutability and onSORT : Context- and Flow-Sensitive Ownership Refinement Types 11 Θ | L | Γ [ x : τ + τ ] (cid:96) x : τ ⇒ Γ [ x ← (cid:45) τ ] ( T-Var ) Θ | L | Γ [ y ← (cid:45) τ ∧ y y = τ x ] , x : ( τ ∧ x x = τ y ) (cid:96) e : τ ⇒ Γ (cid:48) x (cid:54)∈ dom ( Γ (cid:48) ) Θ | L | Γ [ y : τ + τ ] (cid:96) let x = y in e : τ ⇒ Γ (cid:48) ( T-Let ) Θ | L | Γ, x : { ν : int | ν = n } (cid:96) e : τ ⇒ Γ (cid:48) x (cid:54)∈ dom ( Γ (cid:48) ) Θ | L | Γ (cid:96) let x = n in e : τ ⇒ Γ (cid:48) ( T-LetInt ) Θ | L | Γ [ x ← (cid:45) { ν : int | ϕ ∧ ν = 0 } ] (cid:96) e : τ ⇒ Γ (cid:48) Θ | L | Γ [ x ← (cid:45) { ν : int | ϕ ∧ ν (cid:54) = 0 } ] (cid:96) e : τ ⇒ Γ (cid:48) Θ | L | Γ [ x : { ν : int | ϕ } ] (cid:96) ifz x then e else e : τ ⇒ Γ (cid:48) ( T-If ) Θ | L | Γ [ y ← (cid:45) τ ] , x : ( τ ∧ x x = τ y ) ref (cid:96) e : τ ⇒ Γ (cid:48) x (cid:54)∈ dom ( Γ (cid:48) ) Θ | L | Γ [ y : τ + τ ] (cid:96) let x = mkref y in e : τ ⇒ Γ (cid:48) ( T-MkRef ) Θ | L | Γ (cid:96) e : τ (cid:48) ⇒ Γ (cid:48) Θ | L | Γ (cid:48) (cid:96) e : τ (cid:48)(cid:48) ⇒ Γ (cid:48)(cid:48) Θ | L | Γ (cid:96) e ; e : τ (cid:48)(cid:48) ⇒ Γ (cid:48)(cid:48) ( T-Seq ) τ (cid:48) = (cid:40) τ ∧ y y = τ x r > τ r = 0 Θ | L | Γ [ y ← (cid:45) τ (cid:48) ref r ] , x : τ (cid:96) e : τ ⇒ Γ (cid:48) x (cid:54)∈ dom ( Γ (cid:48) ) Θ | L | Γ [ y : ( τ + τ ) ref r ] (cid:96) let x = ∗ y in e : τ ⇒ Γ (cid:48) ( T-Deref ) Γ | = ϕ (cid:15) | Γ (cid:96) WF ϕΘ | L | Γ (cid:96) e : τ ⇒ Γ (cid:48) Θ | L | Γ (cid:96) assert ( ϕ ) ; e : τ ⇒ Γ (cid:48) ( T-Assert ) Fig. 7.
Expression typing rules. refinement types. The typing rules are given in Figures 7 and 8. A typing judgmenttakes the form Θ | L | Γ (cid:96) e : τ ⇒ Γ (cid:48) , which indicates that e is well-typed undera function type environment Θ , typing context L , and type environment Γ , andevaluates to a value of type τ and modifies the input environment according to Γ (cid:48) .Any valid typing derivation must have L (cid:96) WF Γ , L (cid:96) WF Γ (cid:48) , and L | Γ (cid:48) (cid:96) WF τ ,i.e., the input and output type environments and result type must be well-formed.The typing rules in Figure 7 handle the relatively standard features in ourlanguage. The rule T-Seq for sequential composition is fairly straightforwardexcept that the output type environment for e is the input type environment for e . T-LetInt is also straightforward; since x is bound to a constant, it is giventype { ν : int | ν = n } to indicate x is exactly n . The output type environment Γ (cid:48) cannot mention x (expressed with x (cid:54)∈ dom ( Γ (cid:48) )) to prevent x from escaping itsscope. This requirement can be met by applying the subtyping rule (see below) toweaken refinements to no longer mention x . As in other refinement type systems[47], this requirement is critical for ensuring soundness.Rule T-Let is crucial to understanding our ownership type system. Thebody of the let expression e is typechecked under a type environment wherethe type of y in Γ is linearly split into two types: τ for y and τ for the newlycreated binding x . This splitting is expressed using the + operator. If y is a ref-erence type, the split operation distributes some portion of y ’s ownership infor-mation to its new alias x . The split operation also distributes refinement infor-mation between the two types. For example, type { ν : int | ν > } ref can besplit into (1) { ν : int | ν > } ref r and { ν : int | ν > } ref (1 − r ) (for r ∈ (0 , i.e., two immutable references with non-trivial refinement information, or (2) { ν : int | ν > } ref and { ν : int | (cid:62)} ref , where one of the aliases is mutableand the other provides no refinement information. How a type is split dependson the usage of x and y in e . Formally, we define the type addition operator asthe least commutative partial operation that satisfies the following rules: { ν : int | ϕ } + { ν : int | ϕ } = { ν : int | ϕ ∧ ϕ } ( Tadd-Int ) τ ref r + τ ref r = ( τ + τ ) ref r + r ( Tadd-Ref )Viewed another way, type addition describes how to combine two types for thesame value such that the combination soundly incorporates all information fromthe two original types. Critically, the type addition operation cannot create ordestroy ownership and refinement information, only combine or divide it betweentypes. Although not explicit in the rules, by ownership well-formedness, if theentirety of a reference’s ownership is transferred to another type during a split,all refinements in the remaining type must be (cid:62) .The additional bits ∧ y y = τ x and ∧ x x = τ y express equality between x and y as refinements. We use the strengthening operation τ ∧ x ϕ and typed equalityproposition x = τ y , defined respectively as: { ν : int | ϕ } ∧ y ϕ (cid:48) = { ν : int | ϕ ∧ [ ν / y ] ϕ (cid:48) } ( x = { ν : int | ϕ } y ) = ( x = y ) τ ref r ∧ y ϕ (cid:48) = τ ref r ( x = τ ref r y ) = (cid:62) We do not track equality between references or between the contents of aliasedreference cells as doing so would violate our refinement well-formedness condition.These operations are also used in other rules that can introduce equality.Rule
T-MkRef is very similar to
T-Let , except that x is given a referencetype of ownership 1 pointing to τ , which is obtained by splitting the type of y . In T-Deref , the content type of y is split and distributed to x . The strengtheningis conditionally applied depending on the ownership of the dereferenced pointer,that is, if r = 0, τ (cid:48) has to be a maximal type (cid:62) i .Our type system also tracks path information; in the T-If rule, we update therefinement on the condition variable within the respective branches to indicatewhether the variable must be zero. By requiring both branches to produce thesame output type environment, we guarantee that these conflicting refinementsare rectified within the type derivations of the two branches.The type rule for assert statements has the precondition Γ | = ϕ which isdefined to be | = (cid:74) Γ (cid:75) = ⇒ ϕ , i.e., the logical formula (cid:74) Γ (cid:75) = ⇒ ϕ is valid in thechosen theory. (cid:74) Γ (cid:75) lifts the refinements on the integer valued variables into aproposition in the logic used for verification. This denotation operation is definedas: (cid:74) • (cid:75) = (cid:62) (cid:74) { ν : int | ϕ } (cid:75) y = [ y / ν ] ϕ (cid:74) Γ, x : τ (cid:75) = (cid:74) Γ (cid:75) ∧ (cid:74) τ (cid:75) x (cid:74) τ (cid:48) ref r (cid:75) y = (cid:62) If the formula (cid:74) Γ (cid:75) = ⇒ ϕ is valid, then in any context and under any valuationof program variables that satisfy the refinements in (cid:74) Γ (cid:75) , the predicate ϕ must betrue and the assertion must not fail. This intuition forms the foundation of oursoundness claim (Section 3.4). onSORT : Context- and Flow-Sensitive Ownership Refinement Types 13 (The shapes of τ (cid:48) and τ are similar) Θ | L | Γ [ x ← (cid:45) τ ][ y ← (cid:45) ( τ ∧ y y = τ x ) ref ] (cid:96) e : τ ⇒ Γ (cid:48) Θ | L | Γ [ x : τ + τ ][ y : τ (cid:48) ref ] (cid:96) y : = x ; e : τ ⇒ Γ (cid:48) ( T-Assign )( τ ref r + τ ref r ) ≈ ( τ (cid:48) ref r (cid:48) + τ (cid:48) ref r (cid:48) ) Θ | L | Γ [ x ← (cid:45) τ (cid:48) ref r (cid:48) ][ y ← (cid:45) τ (cid:48) ref r (cid:48) ] (cid:96) e : τ ⇒ Γ (cid:48) Θ | L | Γ [ x : τ ref r ][ y : τ ref r ] (cid:96) alias ( x = y ) ; e : τ ⇒ Γ (cid:48) ( T-Alias )( τ ref r + τ ref r ) ≈ ( τ (cid:48) ref r (cid:48) + τ (cid:48) ref r (cid:48) ) Θ | L | Γ [ x ← (cid:45) τ (cid:48) ref r ][ y ← (cid:45) ( τ (cid:48) ref r (cid:48) ) ref r ] (cid:96) e : τ ⇒ Γ (cid:48) Θ | L | Γ [ x : τ ref r ][ y : ( τ ref r ) ref r ] (cid:96) alias ( x = ∗ y ) ; e : τ ⇒ Γ (cid:48) ( T-AliasPtr ) Γ ≤ Γ (cid:48) Θ | L | Γ (cid:48) (cid:96) e : τ ⇒ Γ (cid:48)(cid:48) Γ (cid:48)(cid:48) , τ ≤ Γ (cid:48)(cid:48)(cid:48) , τ (cid:48) Θ | L | Γ (cid:96) e : τ (cid:48) ⇒ Γ (cid:48)(cid:48)(cid:48) ( T-Sub ) τ ≈ τ iff • (cid:96) τ ≤ τ and • (cid:96) τ ≤ τ . Fig. 8.
Pointer manipulation and subtyping Γ | = ϕ = ⇒ ϕ Γ (cid:96) { ν : int | ϕ } ≤ { ν : int | ϕ } ( S-Int ) r ≥ r Γ (cid:96) τ ≤ τ Γ (cid:96) τ ref r ≤ τ ref r ( S-Ref ) ∀ x ∈ dom ( Γ (cid:48) ) .Γ (cid:96) Γ ( x ) ≤ Γ (cid:48) ( x ) Γ ≤ Γ (cid:48) ( S-TyEnv ) Γ, x : τ ≤ Γ (cid:48) , x : τ (cid:48) x (cid:54)∈ dom ( Γ ) Γ, τ ≤ Γ, τ (cid:48) ( S-Res ) Fig. 9.
Subtyping rules.
Destructive Updates, Aliasing, and Subtyping.
We now discuss the handlingof assignment, aliasing annotations, and subtyping as described in Figure 8.Although apparently unrelated, all three concern updating the refinements of(potentially) aliased reference cells.Like the binding forms discussed above,
T-Assign splits the assigned value’stype into two types via the type addition operator, and distributes these typesbetween the right hand side of the assignment and the mutated reference contents.Refinement information in the fresh contents may be inconsistent with anyprevious refinement information; only the shapes must be the same. In a systemwith unrestricted aliasing, this typing rule would be unsound as it would admitwrites that are inconsistent with refinements on aliases of the left hand side.However, the assignment rule requires that the updated reference has an ownershipof 1. By the ownership type invariant, all aliases with the updated reference have 0ownership, and by ownership well-formedness may only contain the (cid:62) refinement.
Example 3.
We can type the program as follows: let x = mkref in // x : { ν : int | ν = 5 } ref let y = x in // x : (cid:62) , y : { ν : int | ν = 5 } ref y := 4; assert (*y = 4) // x : (cid:62) , y : { ν : int | ν = 4 } ref In this and later examples, we include type annotations within comments. Westress that these annotations are for expository purposes only; our tool can inferthese types automatically with no manual annotations.
As described thus far, the type system is quite strict: if ownership has beencompletely transferred from one reference to another, the refinement informationfound in the original reference is effectively useless. Additionally, once a mutablepointer has been split through an assignment or let expression, there is noway to recover mutability. The typing rule for must alias assertions,
T-Alias and
T-AliasPtr , overcomes this restriction by exploiting the must-aliasinginformation to “shuffle” or redistribute ownerships and refinements between twoaliased pointers. The typing rule assigns two fresh types τ (cid:48) ref r (cid:48) and τ (cid:48) ref r (cid:48) tothe two operand pointers. The choice of τ (cid:48) , r (cid:48) , τ (cid:48) , and r (cid:48) is left open providedthat the sum of the new types, ( τ (cid:48) ref r (cid:48) ) + ( τ (cid:48) ref r (cid:48) ) is equivalent (denoted ≈ )to the sum of the original types. Formally, ≈ is defined as in Figure 8; it impliesthat any refinements in the two types must be logically equivalent and thatownerships must also be equal. This redistribution is sound precisely because thetwo references are assumed to alias; the total ownership for the single memorycell pointed to by both references cannot be increased by this shuffling. Further,any refinements that hold for the contents of one reference must necessarily holdfor contents of the other and vice versa. Example 4 (Shuffling ownerships and refinements).
Let ϕ = n be ν = n . let x = mkref in // x : { ν : int | ϕ =5 } ref let y = x in // x : (cid:62) , y : { ν : int | ϕ =5 } ref y := 4; alias (x = y) // x : { ν : int | ϕ =4 } ref . , y : { ν : int | ϕ =4 } ref . The final type assignment for x and y is justified by (cid:62) + { ν : int | ϕ =4 } ref = { ν : int | (cid:62) ∧ ϕ =4 } ref ≈{ ν : int | ϕ =4 ∧ ϕ =4 } ref = { ν : int | ϕ =4 } ref . + { ν : int | ϕ =4 } ref . . The aliasing rules give fine-grained control over ownership information. Thisflexibility allows mutation through two or more aliased references within thesame scope. Provided sufficient aliasing annotations, the type system may shuffleownerships between one or more live references, enabling and disabling mutabilityas required. Although the reliance on these annotations appears to decrease thepracticality of our type system, we expect these aliasing annotations can beinserted by a conservative must-aliasing analysis. Further, empirical experiencefrom our prior work [56] indicates that only a small number of annotations arerequired for larger programs.
Example 5 (Shuffling Mutability).
Let ϕ = n again be ν = n . The followingprogram uses two live, aliased references to mutate the same memory location: let x = mkref inlet y = x in // x : { ν : int | ϕ =0 } ref , y : (cid:62) x := 1; alias (x = y); // x : (cid:62) , y : { ν : int | ϕ =1 } ref y := 2; alias (x = y); // x : { ν : int | ϕ =2 } ref . , y : { ν : int | ϕ =2 } ref . assert (*x = 2) onSORT : Context- and Flow-Sensitive Ownership Refinement Types 15 Θ ( f ) = ∀ λ. (cid:104) x : τ , . . . , x n : τ n (cid:105) → (cid:104) x : τ (cid:48) , . . . , x n : τ (cid:48) n | τ (cid:105) σ α = [ (cid:96) : L /λ ] σ x = [ y / x ] · · · [ y n / x n ] Θ | L | Γ [ y i ← (cid:45) σ α σ x τ (cid:48) i ] , x : σ α σ x τ (cid:96) e : τ (cid:48) ⇒ Γ (cid:48) x (cid:54)∈ dom ( Γ (cid:48) ) Θ | L | Γ [ y i : σ α σ x τ i ] (cid:96) let x = f (cid:96) ( y , . . . , y n ) in e : τ (cid:48) ⇒ Γ (cid:48) ( T-Call ) Θ ( f ) = ∀ λ. (cid:104) x : τ , . . . , x n : τ n (cid:105) → (cid:104) x : τ (cid:48) , . . . , x n : τ (cid:48) n | τ (cid:105) Θ | λ | x : τ , . . . , x n : τ n (cid:96) e : τ ⇒ x : τ (cid:48) , . . . , x n : τ (cid:48) n Θ (cid:96) f (cid:55)→ ( x , .. , x n ) e ( T-FunDef ) ∀ f (cid:55)→ ( x , .. , x n ) e ∈ D .Θ (cid:96) f (cid:55)→ ( x , .. , x n ) edom ( D ) = dom ( Θ ) Θ (cid:96) D ( T-Funs ) Θ (cid:96) D (cid:96) WF ΘΘ | (cid:15) | • (cid:96) e : τ ⇒ Γ (cid:96) (cid:104) D , e (cid:105) ( T-Prog ) Fig. 10.
Program typing rules
After the first aliasing statement the type system shuffles the (exclusive) mutabilitybetween x and y to enable the write to y . After the second aliasing statementthe ownership in y is split with x ; note that transferring all ownership from y to x would also yield a valid typing.Finally, we describe the subtyping rule. The rules for subtyping types andenvironments are shown in Figure 9. For integer types, the rules require therefinement of a supertype is a logical consequence of the subtype’s refinementconjoined with the lifting of Γ . The subtype rule for references is covariant inthe type of reference contents. It is widely known that in a language with un-restricted aliasing and mutable references such a rule is unsound: after a writeinto the coerced pointer, reads from an alias may yield a value disallowed bythe alias’ type [43]. However, as in the assign case, ownership types prevent un-soundness; a write to the coerced pointer requires the pointer to have ownership1, which guarantees any aliased pointers have the maximal type and provide noinformation about their contents beyond simple types. We now turn to a discussion of the interprocedural fragment of our language,and how our type system propagates context information. The remaining typingrules for our language are shown in Figure 10. These rules concern the typing offunction calls, function bodies, and entire programs.We first explain the
T-Call rule. The rule uses two substitution maps. σ x translates between the parameter names used in the function type and actualargument names at the call-site. σ α instantiates all occurrences of λ in the calleetype with (cid:96) : L , where (cid:96) is the label of the call-site and L the typing context ofthe call. The types of the arguments y i ’s are required to match the parameter types (post substitution). The body of the let binding is then checked withthe argument types updated to reflect the changes in the function call (again,post substitution). This update is well-defined because we require all functionarguments be distinct as described in Section 2.1. Intuitively, the substitution σ α represents incrementally refining the behavior of the callee function with partialcontext information. If L is itself a context variable λ (cid:48) , this substitution effectivelytransforms any context prefix queries over λ in the argument/return/outputtypes into a queries over (cid:96) : λ (cid:48) . In other words, while the exact concrete executioncontext of the callee is unknown, the context must at least begin with (cid:96) whichcan potentially rule out certain behaviors.Rule T-FunDef type checks a function definition f (cid:55)→ ( x , .. , x n ) e againstthe function type given in Θ . As a convenience we assume that the parameternames in the function type match the formal parameters in the function definition.The rule checks that under an initial environment given by the argument types thefunction body produces a value of the return type and transforms the argumentsaccording to the output types. As mentioned above, functions may be executedunder many different contexts, so type checking the function body is performedunder the context variable λ that occurs in the function type.Finally, the rule for typing programs ( T-Prog ) checks that all functiondefinitions are well typed under a well-formed function type environment, andthat the entry point e is well typed in an empty type environment and the typingcontext (cid:15) , i.e., the initial context. Example 6 (1-CFA).
Recall the program in Figure 3 in Section 1; assume thefunction calls are labeled as follows: p := get (cid:96) (p) + 1;// ...q := get (cid:96) (q) + 1; Taking τ p to be the type shown in Example 2: { ν : int | ( (cid:96) (cid:22) λ = ⇒ ν = 3) ∧ ( (cid:96) (cid:22) λ = ⇒ ν = 5) } we can give get the type ∀ λ. (cid:10) z : τ p ref (cid:11) → (cid:10) z : τ p ref | τ p (cid:11) . Example 7 (2-CFA).
To see how context information propagates across multiplecalls, consider the following change to the code considered in Example 6: get_real(z) { *z }get(z) { get_real (cid:96) (z) } The type of get remains as in Example 6, and taking τ to be { ν : int | ( (cid:96) (cid:96) (cid:22) λ (cid:48) = ⇒ ν = 3) ∧ ( (cid:96) (cid:96) (cid:22) λ (cid:48) = ⇒ ν = 5) } the type of get_real is: ∀ λ (cid:48) . (cid:10) z : τ ref (cid:11) → (cid:10) z : τ ref | τ (cid:11) .We focus on the typing of the call to get_real in get ; it is typed in context λ and a type environment where p is given type τ p from Example 6. onSORT : Context- and Flow-Sensitive Ownership Refinement Types 17 Applying the substitution [ (cid:96) : λ/λ (cid:48) ] to the argument type of get_real yields: { ν : int | ( (cid:96) (cid:96) (cid:22) (cid:96) : λ = ⇒ ν = 3) ∧ ( (cid:96) (cid:96) (cid:22) (cid:96) : λ = ⇒ ν = 5) } ref ≈{ ν : int | ( (cid:96) (cid:22) λ = ⇒ ν = 3) ∧ ( (cid:96) (cid:22) λ = ⇒ ν = 5) } ref which is exactly the type of p . A similar derivation applies to the return type of get_real and thus get . We have proven that any program that type checks according to the rules abovewill never experience an assertion failure. We formalize this claim with thefollowing soundness theorem.
Theorem 1 (Soundness). If (cid:96) (cid:104) D , e (cid:105) , then (cid:104)∅ , ∅ , · , e (cid:105) (cid:54)−→ ∗ D AssertFail .Further, any well-typed program either diverges, halts in the configuration
AliasFail , or halts in a configuration (cid:104) H , R , · , x (cid:105) for some H , R and x , i.e.,evaluation does not get stuck.Proof (Sketch).
By standard progress and preservation lemmas; the full proof hasbeen omitted for space reasons and can be found in the accompanying appendix.
We now briefly describe the inference algorithm implemented in our tool
Con-SORT . We sketch some implemented extensions needed to type more interestingprograms and close with a discussion of current limitations of our prototype.
Our tool first runs a standard, simple type inference algorithm to generate typetemplates for every function parameter type, return type, and for every livevariable at each program point. For a variable x of simple type τ S ::= int | τ S ref at program point p , ConSORT generates a type template (cid:74) τ S (cid:75) x , ,p as follows: (cid:74) int (cid:75) x ,n,p = { ν : int | ϕ x ,n,p ( ν ; FV p ) } (cid:74) τ S ref (cid:75) x ,n,p = (cid:74) τ S (cid:75) x ,n +1 ,p ref r x ,n,p ϕ x ,n,p ( ν ; FV p ) denotes a fresh relation symbol applied to ν and the free variablesof simple type int at program point p (denoted FV p ). r x ,n,p is a fresh ownershipvariable. For each function f , there are two synthetic program points, f b and f e for the beginning and end of the function respectively. At both points, ConSORT generates type template for each argument, where FV f b and FV f e are the namesof integer typed parameters. At f e , ConSORT also generates a type templatefor the return value. We write Γ p to indicate the type environment at point p ,where every variable is mapped to its corresponding type template. (cid:74) Γ p (cid:75) is thusequivalent to (cid:86) x ∈ FV p ϕ x , ,p ( x ; FV p ). When generating these type templates, our implementation also generates own-ership well-formedness constraints. Specifically, for a type template of the form { ν : int | ϕ x ,n +1 ,p ( ν ; FV p ) } ref r x ,n,p ConSORT emits the constraint: r x ,n,p =0 = ⇒ ϕ x ,n +1 ,p ( ν ; FV p ) and for a type template ( τ ref r x ,n +1 ,p ) ref r x ,n,p Con-SORT emits the constraint r x ,n,p = 0 = ⇒ r x ,n +1 ,p = 0. ConSORT then walks the program, generating constraints between relationsymbols and ownership variables according to the typing rules. These constraintstake three forms, ownership constraints, subtyping constraints, and assertionconstraints. Ownership constraints are simple linear (in)equalities over ownershipvariables and constants, according to conditions imposed by the typing rules.For example, if variable x has the type template τ ref r x , ,p for the expression x : = y ; e at point p , ConSORT generates the constraint r x , ,p = 1. ConSORT emits subtyping constraints between the relation symbols atrelated program points according to the rules of the type system. For example, forthe term let x = y in e at program point p (where e is at program point p (cid:48) , and x has simple type int ref ) ConSORT generates the following subtyping constraint: (cid:74) Γ p (cid:75) ∧ ϕ y , ,p ( ν ; FV p ) = ⇒ ϕ y , ,p (cid:48) ( ν ; FV p (cid:48) ) ∧ ϕ x , ,p (cid:48) ( ν ; FV p (cid:48) )in addition to the ownership constraint r y , ,p = r y , ,p (cid:48) + r x , ,p (cid:48) .Finally, for each assert ( ϕ ) in the program, ConSORT emits an assertionconstraint of the form: (cid:74) Γ p (cid:75) = ⇒ ϕ which requires the refinements on integertyped variables in scope are sufficient to prove ϕ . Encoding Context Sensitivity.
To make inference tractable, we require the userto fix a priori the maximum length of prefix queries to a constant k (this choiceis easily controlled with a command line parameter to our tool). We supplementthe arguments in every predicate application with a set of integer context vari-ables c , . . . , c k ; these variables do not overlap with any program variables. ConSORT uses these variables to infer context sensitive refinements asfollows. Consider a function call let x = f (cid:96) ( y , . . . , y n ) in e at point p where e is at point p (cid:48) . ConSORT generates the following constraint for a refinement ϕ y i ,n,p ( ν, c , . . . , c k ; FV p ) which occurs in the type template of y i : ϕ y i ,n,p ( ν, c , . . . , c k ; FV p ) = ⇒ σ x ϕ x i ,n, f b ( ν, (cid:96), c , . . . , c k − ; FV f b ) σ x ϕ x i ,n, f e ( ν, (cid:96), c , . . . , c k − ; FV f e ) = ⇒ ϕ y i ,n,p (cid:48) ( ν, c , . . . , c k ; FV p (cid:48) ) σ x = [ y / x ] · · · [ y n / x n ]Effectively, we have encoded (cid:96) . . . (cid:96) k (cid:22) λ as ∧
The results of the above process are two systems of con-straints; real arithmetic constraints over ownership variables and constrained Horn onSORT : Context- and Flow-Sensitive Ownership Refinement Types 19 clauses (CHC) over the refinement relations. Under certain assumptions about thesimple types in a program, the size of the ownership and subtyping constraints willbe polynomial to the size of the program. These systems are not independent; therelation constraints may mention the value of ownership variables due to the well-formedness constraints described above. The ownership constraints are first solvedwith Z3 [16]. These constraints are non-linear but Z3 appears particularly well-engineered to quickly find solutions for the instances generated by
ConSORT . Weconstrain Z3 to maximize the number of non-zero ownership variables to ensure asfew refinements as possible are constrained to be (cid:62) by ownership well-formedness.The values of ownership variables inferred by Z3 are then substituted into theconstrained Horn clauses, and the resulting system is checked for satisfiabilitywith an off-the-shelf CHC solver. Our implementation generates constraints inthe industry standard SMT-Lib2 format [8]; any solver that accepts this formatcan be used as a backend for
ConSORT . Our implementation currently supportsSpacer [37] (part of the Z3 solver [16]), HoICE [13], and Eldarica [48] (adding anew backend requires only a handful of lines of glue code). We found that differentsolvers are better tuned to different problems; we also implemented parallel mode which runs all supported solvers in parallel, using the first available result.
Primitive Operations.
As defined in Section 2, our language can compare integersto zero and load and store them from memory, but can perform no meaningfulcomputation over these numbers. To promote the flexibility of our type systemand simplify our soundness statement, we do not fix a set of primitive operationsand their static semantics. Instead, we assume any set of primitive operationsused in a program are given sound function types in Θ . For example, under theassumption that + has its usual semantics and the underlying logic supports +, wecan give + the type ∀ λ. (cid:104) x : (cid:62) , y : (cid:62) (cid:105) → (cid:104) x : (cid:62) , y : (cid:62) | { ν : int | ν = x + y }(cid:105) .Interactions with a nondeterministic environment or unknown program inputscan then be modeled with a primitive that returns integers refined with (cid:62) . Dependent Tuples.
Our implementation supports types of the form: ( x : τ , . . . , x n : τ n ), where x i can appear within τ j ( j (cid:54) = i ) if τ i is an integer type. Forexample, ( x : { ν : int | (cid:62)} , y : { ν : int | ν > x } ) is the type of tuples whose secondelement is strictly greater than the first. We also extend the language with tupleconstructors as a new value form, and let bindings with tuple patterns as the LHS.The extension to type checking is relatively straightforward; the only signifi-cant extensions are to the subtyping rules. Specifically, the subtyping check for atuple element x i : τ i is performed in a type environment elaborated with the typesand names of other tuple elements. The extension to type inference is also straight-forward; the arguments for a predicate symbol include any enclosing dependenttuple names and the environment in subtyping constraints is likewise extended. Recursive Types.
Our language also supports some unbounded heap structuresvia recursive reference types. To keep inference tractable, we forbid nested recur-sive types, multiple occurrences of the recursive type variable, and additionally fix the shape of refinements that occur within a recursive type. For recursive re-finements that fit the above restriction, our approach for refinements is broadlysimilar to that in [35], and we use the ownership scheme of [56] for handlingownership. We first use simple type inference to infer the shape of the recursivetypes, and automatically insert fold/unfold annotations into the source program.As in [35], the refinements within an unfolding of a recursive type may refer todependent tuple names bound by the enclosing type. These recursive types canexpress, e.g., the invariants of a mutable, sorted list. As in [56], recursive typesare unfolded once before assigning ownership variables; further unfoldings copyexisting ownership variables.As in Java or C++, our language does not support sum types, and anyinstantiation of a recursive type must use a null pointer. Our implementationsupports an ifnull construct in addition to a distinguished null constant. Ourimplementation allows any refinement to hold for the null constant, including ⊥ . Currently, our implementation does not detect null pointer dereferences, andall soundness guarantees are made modulo freedom of null dereferences. As (cid:74) Γ (cid:75) omits refinements under reference types, null pointer refinements do not affectthe verification of programs without null pointer dereferences. Arrays.
Our implementation supports arrays of integers. Each array is given anownership describing the ownership of memory allocated for the entire array. Thearray type contains two refinements: the first refines the length of the array itself,and the second refines the entire array contents. The content refinement mayrefer to a symbolic index variable for precise, per-index refinements. At readsand writes to the array,
ConSORT instantiates the refinement’s symbolic indexvariable with the concrete index used at the read/write.As in [56], our restriction to arrays of integers stems from the difficulty ofownership inference. Soundly handling pointer arrays requires index-wise trackingof ownerships which significantly complicates automated inference. We leavesupporting arrays of pointers to future work.
Our current approach is not complete; there are safe programs that will be rejectedby our type system. As mentioned in Section 3.1, our well-formedness conditionforbids refinements that refer to memory locations. As a result,
ConSORT cannot in general express, e.g., that the contents of two references are equal.Further, due to our reliance on automated theorem provers we are restricted tologics with sound but potentially incomplete decision procedures.
ConSORT also does not support conditional or context-sensitive ownerships, and thereforecannot precisely handle conditional mutation or aliasing.
We now present the results of preliminary experiments performed with the imple-mentation described in Section 4. The goal of these experiments was to answer the onSORT : Context- and Flow-Sensitive Ownership Refinement Types 21
Table 1.
Description of benchmark suite adapted from JayHorn.
Java are programsthat test Java-specific features.
Inc are tests that cannot be handled by
ConSORT , e.g.,null checking, etc.
Bug includes a “safe” program we discovered was actually incorrect.
Set Orig. Adapted Java Inc Bug
Safe 41 32 6 2 1Unsafe 41 26 13 2 0 following questions: i) is the type system (and extensions of Section 4) expressiveenough to type and verify non-trivial programs? and ii) is type inference feasible?To answer these questions, we evaluated our prototype implementation on twosets of benchmarks. The first set is adapted from JayHorn [32, 33], a verificationtool for Java. This test suite contains a combination of 82 safe and unsafeprograms written in Java. We chose this benchmark suite as, like
ConSORT ,JayHorn is concerned with the automated verification of programs in a languagewith mutable, aliased memory cells. Further, although some of their benchmarkprograms tested Java specific features, most could be adapted into our low-levellanguage. The tests we could adapt provide a comparison with existing state-of-the-art verification techniques. A detailed breakdown of the adapted benchmarksuite can be found in Table 1.
Remark 2.
The original JayHorn paper includes two additional benchmark sets,Mine Pump and CBMC. Both our tool and recent JayHorn versions time out onthe Mine Pump benchmark. Further, the CBMC tests were either subsumed byour own test programs, tested Java specific features, or tested program synthesisfunctionality. We therefore omitted both of these benchmarks from our evaluation.The second benchmark set consists of data structure implementations andmicrobenchmarks written directly in our low-level imperative language. Wedeveloped this suite to test the expressive power of our type system and inference.The programs included in this suite are: – Array-List
Implementation of an unbounded list backed by an array. – Sorted-List
Implementation of a mutable, sorted list maintained with anin-place insertion sort algorithm. – Shuffle
Multiple live references are used to mutate the same location inprogram memory as in Example 5. – Mut-List
Implementation of general linked lists with a clear operation. – Array-Inv
A program which allocates a length n array and writes the value i at every index i . – Intro2 The motivating program shown in Figure 2 in Section 1. Our experiments and the
ConSORT
Table 2.
Comparison of
ConSORT to JayHorn on the benchmark set of [32] (top)and our custom benchmark suite (bottom).
T/O indicates a time out.
ConSORT JayHornSet N. Tests
Correct T/O Correct T/O Imp.
Safe
32 29 3 24 5 3
Unsafe
26 26 0 19 0 7
Name Safe? Time(s) Ann JH Name Safe? Time(s) Ann JHArray-Inv (cid:88)
Array-Inv-BUG X Array-List (cid:88)
Array-List-BUG X Intro2 (cid:88)
Intro2-BUG X Mut-List (cid:88)
Mut-List-BUG X Shuffle (cid:88) (cid:88)
Shuffle-BUG X X Sorted-List (cid:88)
Sorted-List-BUG X We introduced unsafe mutations to these programs to check our tool for unsound-ness and translated these programs into Java for further comparison with JayHorn.Our benchmarks and JayHorn’s require a small number of trivially identi-fied alias annotations. The adapted JayHorn benchmarks contain a total of 6annotations; the most for any individual test was 3. The number of annotationsrequired for our benchmark suite are shown in column
Ann. of Table 2.We first ran
ConSORT on each program in our benchmark suite and ranversion 0.7 of JayHorn on the corresponding Java version. We recorded the finalverification result for both our tool and JayHorn. We also collected the end-to-endruntime of
ConSORT for each test; we do not give a performance comparisonwith JayHorn given the many differences in target languages. For the JayHornsuite, we first ran our tool on the adapted version of each test program and ranJayHorn on the original Java version. We also did not collect runtime informationfor this set of experiments because our goal is a comparison of tool precision, notperformance. All tests were run on a machine with 16 GB RAM and 4 Intel i5CPUs at 2GHz and with a timeout of 60 seconds (the same timeout was used in[32]). We used
ConSORT ’s parallel backend (Section 4) with Z3 version 4.8.4,HoICE version 1.8.1, and Eldarica version 2.0.1 and JayHorn’s Eldarica backend.
The results of our experiments are shown in Table 2. On the JayHorn benchmarksuite
ConSORT performs competitively with JayHorn, correctly identifying 29of the 32 safe programs as such. For all 3 tests on which
ConSORT timed outafter 60 seconds, JayHorn also timed out (column
T/O ). For the unsafe programs,
ConSORT correctly identified all programs as unsafe within 60 seconds; JayHornanswered
Unknown for 7 tests (column
Imp. ).On our own benchmark set,
ConSORT correctly verifies all safe versions ofthe programs within 60 seconds. For the unsafe variants,
ConSORT was able to onSORT : Context- and Flow-Sensitive Ownership Refinement Types 23 quickly and definitively determine these programs unsafe. JayHorn times out onall tests except for
Shuffle and
ShuffleBUG (column JH ). We investigated thecause of time outs and discovered that after verification failed with an unboundedheap model, JayHorn attempts verification on increasingly larger bounded heaps.In every case, JayHorn exceeded the 60 second timeout before reaching a pre-configured limit on the heap bound. This result suggests JayHorn struggles inthe presence of per-object invariants and unbounded allocations; the only twotests JayHorn successfully analyzed contain just a single object allocation.We do not believe this struggle is indicative of a shortcoming in JayHorn’simplementation, but stems from the fundamental limitations of JayHorn’s memoryrepresentation. Like many verification tools (see Section 6), JayHorn uses a single,unchanging invariant to for every object allocated at the same syntactic location;effectively, all objects allocated at the same location are assumed to alias with oneanother. This representation cannot, in general, handle programs with differentinvariants for distinct objects that evolve over time. We hypothesize other toolsthat adopt a similar approach will exhibit the same difficulty. The difficulty in handling programs with mutable references and aliasing has beenwell-studied. Like JayHorn, many approaches model the heap explicitly at ver-ification time, approximating concrete heap locations with allocation site labels[14, 20, 32, 33, 46]; each abstract location is also associated with a refinement. Asabstract locations summarize many concrete locations, this approach does not ingeneral admit strong updates and flow-sensitivity; in particular, the refinementassociated with an abstract location is fixed for the lifetime of the program. Thetechniques cited above include various workarounds for this limitation. For exam-ple, [14, 46] temporarily allows breaking these invariants through a distinguishedprogram name as long as the abstract location is not accessed through anothername. The programmer must therefore eventually bring the invariant back insync with the summary location. As a result, these systems ultimately cannotprecisely handle programs that require evolving invariants on mutable memory.A similar approach was taken in CQual [23] by Aiken et al. [2]. They usedan explicit restrict binding for pointers. Strong updates are permitted throughpointers bound with restrict , but the program is forbidden from using any pointerswhich share an allocation site while the restrict binding is live.A related technique used in the field of object-oriented verification is to declareobject invariants at the class level and allow these invariants on object fields to bebroken during a limited period of time [7, 22]. In particular, the work on Spec a owns object b ; like ConSORT ’s ownership system, these ownerships contain the effects of mutation.However, Spec b outside of the owning object a .Viper [30, 42] (and its related projects [31, 39]) uses access annotations (ex-pressed as permission predicates) to explicitly transfer access/mutation permis- sions for references between static program names. Like ConSORT , permissionsmay be fractionally transferred, allowing temporary shared, immutable access toa mutable memory cell. However, while
ConSORT automatically infers manyownership transfers, Viper requires extensive annotations for each transfer.F*, a dependently typed dialect of ML, includes an update/select theory ofheaps and requires explicit annotations summarizing the heap effects of a method[44, 57, 58]. This approach enables modular reasoning and precise specification ofpre- and post-conditions with respect to the heap, but precludes full automation.The work on rely–guarantee reference types by Gordon et al. [26, 27] uses re-finement types in a language mutable references and aliasing. Their approach ex-tends reference types with rely/guarantee predicates; the rely predicate describespossible mutations via aliases, and the guarantee predicate describes the admissi-ble mutations through the current reference. If two references may alias, then theguarantee predicate of one reference implies the rely predicate of the other andvice versa. This invariant is maintained with a splitting operation that is similarto our + operator. Further, their type system allows strong updates to referencerefinements provided the new refinements are preserved by the rely predicate.Thus, rely–guarantee refinement support multiple mutable, aliased referenceswith non-trivial refinement information. Unfortunately this expressiveness comesat the cost of automated inference and verification; an embedding of this systeminto Liquid Haskell [62] described in [27] was forced to sacrifice strong updates.Work by Degen et al. [17] introduced linear state annotations to Java. To effectstrong updates in the presence of aliasing, like
ConSORT , their system requiresannotated memory locations are mutated only through a distinguished reference.Further, all aliases of this mutable reference give no information about the stateof the object much like our 0 ownership pointers. However, their system cannothandle multiple, immutable aliases with non-trivial annotation information; only the mutable reference may have non-trivial annotation information.The fractional ownerships in
ConSORT and their counterparts in [55, 56]have a clear relation to linear type systems. Many authors have explored theuse of linear type systems to reason in contexts with aliased mutable references[18, 19, 52], and in particular with the goal of supporting strong updates [1].A closely related approach is RustHorn by Matsushita et al. [40]. Much like
ConSORT , RustHorn uses CHC and linear aliasing information for the soundand—unlike
ConSORT —complete verification of programs with aliasing andmutability. However, their approach depends on Rust’s strict borrowing discipline ,and cannot handle programs where multiple aliased references are used in thesame lexical region. In contrast,
ConSORT supports fine-grained, per-statementchanges in mutability and even further control with alias annotations, whichallows it to verify larger classes of programs.The ownerships of
ConSORT also have a connection to separation logic[45]; the separating conjunction isolates write effects to local subheaps, while
ConSORT ’s ownership system isolates effects to local updates of pointer types.Other researchers have used separation logic to precisely support strong updatesof abstract state. For example, in work by Kloos et al. [36] resources are associated onSORT : Context- and Flow-Sensitive Ownership Refinement Types 25 with static, abstract names; each resource (represented by its static name) maybe owned (and thus, mutated) by exactly one thread. Unlike
ConSORT , theirownership system forbids even temporary immutable, shared ownership, ortransferring ownerships at arbitrary program points. An approach proposed byBakst and Jhala [4] uses a similar technique, combining separation logic withrefinement types. Their approach gives allocated memory cells abstract names, andassociates these names with refinements in an abstract heap. Like the approachof Kloos et al. and
ConSORT ’s ownership 1 pointers, they ensure these abstractlocations are distinct in all concrete heaps, enabling sound, strong updates.The idea of using a rational number to express permissions to access a refer-ence dates back to the type system of fractional permissions by Boyland [12]. Hiswork used fractional permissions to verify race freedom of a concurrent programwithout a may-alias analysis. Later, Terauchi [59] proposed a type-inference algo-rithm that reduces typing constraints to a set of linear inequalities over rationalnumbers. Boyland’s idea also inspired a variant of separation logic for a concurrentprogramming language [11] to express sharing of read permissions among severalthreads. Our previous work [55, 56], inspired by that in [11, 59], proposed meth-ods for type-based verification of resource-leak freedom, in which a rational num-ber expresses an obligation to deallocate certain resource, not just a permission.The issue of context-sensitivity (sometimes called polyvariance ) is well-studiedin the field of abstract interpretation (e.g., [28, 34, 41, 50, 51], see [25] for a recentsurvey). Polyvariance has also been used in type systems to assign different behav-iors to the same function depending on its call site [3, 6, 63]. In the area of refine-ment type systems, Zhu and Jagannathan developed a context-sensitive dependenttype system for a functional language [66] that indexed function types by uniquelabels attached to call-sites. Our context-sensitivity approach was inspired by thiswork. In fact, we could have formalized context-polymorphism within the frame-work of full dependent types, but chose the current presentation for simplicity.
We presented
ConSORT , a novel type system for safety verification of imperativeprograms with mutability and aliasing.
ConSORT is built upon the novel combi-nation of fractional ownership types and refinement types. Ownership types flow-sensitively and precisely track the existence of mutable aliases.
ConSORT admitssound strong updates by discarding refinement information on mutably-aliasedreferences as indicated by ownership types. Our type system is amenable to auto-matic type inference; we have implemented a prototype of this inference tool andfound it can verify several non-trivial programs and outperforms a state-of-the-artprogram verifier. As an area of future work, we plan to investigate using fractionalownership types to soundly allow refinements that mention memory locations.
Acknowledgments
The authors would like to the reviewers for their thoughtful feedbackand suggestions, and Yosuke Fukuda and Alex Potanin for their feedback on early drafts.This work was supported in part by JSPS KAKENHI, grant numbers JP15H05706 andJP19H04084, and in part by the JST ERATO MMSD Project.6 J. Toman et al.
Bibliography [1] Ahmed, A., Fluet, M., Morrisett, G.: L : a linear language with locations.Fundamenta Informaticae (4), 397–449 (2007)[2] Aiken, A., Foster, J.S., Kodumal, J., Terauchi, T.: Checking andinferring local non-aliasing. In: Conference on Programming Lan-guage Design and Implementation (PLDI). pp. 129–140 (2003).https://doi.org/10.1145/781131.781146[3] Amtoft, T., Turbak, F.: Faithful translations between polyvariant flows andpolymorphic types. In: European Symposium on Programming (ESOP). pp.26–40. Springer (2000). https://doi.org/10.1007/3-540-46425-5 2[4] Bakst, A., Jhala, R.: Predicate abstraction for linked data struc-tures. In: Conference on Verification, Model Checking, and Abstract In-terpretation (VMCAI). pp. 65–84. Springer Berlin Heidelberg (2016).https://doi.org/10.1007/978-3-662-49122-5 3[5] Ball, T., Levin, V., Rajamani, S.K.: A decade of software model check-ing with SLAM. Communications of the ACM (7), 68–76 (2011).https://doi.org/10.1145/1965724.1965743[6] Banerjee, A.: A modular, polyvariant and type-based closure analysis. In:International Conference on Functional Programming (ICFP). pp. 1–10(1997). https://doi.org/10.1145/258948.258951[7] Barnett, M., F¨ahndrich, M., Leino, K.R.M., M¨uller, P., Schulte, W., Venter,H.: Specification and verification: the Spec (6), 81–91 (2011). https://doi.org/10.1145/1953122.1953145[8] Barrett, C., Fontaine, P., Tinelli, C.: The Satisfiability Modulo TheoriesLibrary (SMT-LIB). (2016)[9] Bengtson, J., Bhargavan, K., Fournet, C., Gordon, A.D., Maffeis, S.: Re-finement types for secure implementations. ACM Transactions on Pro-gramming Languages and Systems (TOPLAS) (2), 8:1–8:45 (2011).https://doi.org/10.1145/1890028.1890031[10] Bhargavan, K., Bond, B., Delignat-Lavaud, A., Fournet, C., Hawblitzel,C., Hrit¸cu, C., Ishtiaq, S., Kohlweiss, M., Leino, R., Lorch, J., Mail-lard, K., Pan, J., Parno, B., Protzenko, J., Ramananandro, T., Rane, A.,Rastogi, A., Swamy, N., Thompson, L., Wang, P., Zanella-B´eguelin, S.,Zinzindohou´e, J.K.: Everest: Towards a verified, drop-in replacement ofHTTPS. In: Summit on Advances in Programming Languages (SNAPL2017). pp. 1:1–1:12. Schloss Dagstuhl-Leibniz-Zentrum fuer Informatik (2017).https://doi.org/10.4230/LIPIcs.SNAPL.2017.1[11] Bornat, R., Calcagno, C., O’Hearn, P.W., Parkinson, M.J.: Per-mission accounting in separation logic. In: Symposium on Prin-ciples of Programming Languages (POPL). pp. 259–270 (2005).https://doi.org/10.1145/1040305.1040327[12] Boyland, J.: Checking interference with fractional permissions. In:Symposion on Static Analysis (SAS). pp. 55–72. Springer (2003).https://doi.org/10.1007/3-540-44898-5 4 onSORT : Context- and Flow-Sensitive Ownership Refinement Types 27 [13] Champion, A., Kobayashi, N., Sato, R.: HoIce: An ICE-based non-linear Hornclause solver. In: Asian Symposium on Programming Languages and Systems(APLAS). pp. 146–156. Springer (2018). https://doi.org/10.1007/978-3-030-02768-1 8[14] Chugh, R., Herman, D., Jhala, R.: Dependent types for JavaScript. In: Confer-ence on Object Oriented Programming Systems Languages and Applications(OOPSLA). pp. 587–606 (2012). https://doi.org/10.1145/2384616.2384659[15] Cousot, P., Cousot, R., Feret, J., Mauborgne, L., Min´e, A., Monniaux, D.,Rival, X.: The ASTR´EE analyzer. In: European Symposium on Programming(ESOP). pp. 21–30. Springer (2005). https://doi.org/10.1007/978-3-540-31987-0 3[16] De Moura, L., Bjørner, N.: Z3: An efficient SMT solver. In: Conference onTools and Algorithms for the Construction and Analysis of Systems (TACAS).pp. 337–340. Springer (2008). https://doi.org/10.1007/978-3-540-78800-3 24[17] Degen, M., Thiemann, P., Wehr, S.: Tracking linear and affine resourceswith JAVA(X). In: European Conference on Object-Oriented Programming(ECOOP). pp. 550–574. Springer (2007). https://doi.org/10.1007/978-3-540-73589-2 26[18] DeLine, R., F¨ahndrich, M.: Enforcing high-level protocols in low-level soft-ware. In: Conference on Programming Language Design and Implementation(PLDI). pp. 59–69 (2001). https://doi.org/10.1145/378795.378811[19] F¨ahndrich, M., DeLine, R.: Adoption and focus: Practical lineartypes for imperative programming. In: Conference on ProgrammingLanguage Design and Implementation (PLDI). pp. 13–24 (2002).https://doi.org/10.1145/512529.512532[20] Fink, S.J., Yahav, E., Dor, N., Ramalingam, G., Geay, E.: Effective type-state verification in the presence of aliasing. ACM Transactions on Soft-ware Engineering and Methodology (TOSEM) (2), 9:1–9:34 (2008).https://doi.org/10.1145/1348250.1348255[21] Flanagan, C.: Hybrid type checking. In: Symposium on Prin-ciples of Programming Languages (POPL). pp. 245–256 (2006).https://doi.org/10.1145/1111037.1111059[22] Flanagan, C., Leino, K.R.M., Lillibridge, M., Nelson, G., Saxe, J.B.,Stata, R.: Extended static checking for Java. In: Conference on Program-ming Language Design and Implementation (PLDI). pp. 234–245 (2002).https://doi.org/10.1145/512529.512558[23] Foster, J.S., Terauchi, T., Aiken, A.: Flow-sensitive type qualifiers. In:Conference on Programming Language Design and Implementation (PLDI).pp. 1–12 (2002). https://doi.org/10.1145/512529.512531[24] Freeman, T., Pfenning, F.: Refinement types for ML. In: Conference onProgramming Language Design and Implementation (PLDI). pp. 268–277(1991). https://doi.org/10.1145/113445.113468[25] Gilray, T., Might, M.: A survey of polyvariance in abstract interpretations.In: Symposium on Trends in Functional Programming. pp. 134–148. Springer(2013). https://doi.org/10.1007/978-3-642-45340-3 9 [26] Gordon, C.S., Ernst, M.D., Grossman, D.: Rely–guarantee references forrefinement types over aliased mutable data. In: Conference on Program-ming Language Design and Implementation (PLDI). pp. 73–84 (2013).https://doi.org/10.1145/2491956.2462160[27] Gordon, C.S., Ernst, M.D., Grossman, D., Parkinson, M.J.: Verifying invari-ants of lock-free data structures with rely–guarantee and refinement types.ACM Transactions on Programming Languages and Systems (TOPLAS) (3), 11:1–11:54 (2017). https://doi.org/10.1145/3064850[28] Hardekopf, B., Wiedermann, B., Churchill, B., Kashyap, V.: Widening forcontrol-flow. In: Conference on Verification, Model Checking, and AbstractInterpretation (VMCAI). pp. 472–491 (2014). https://doi.org/10.1007/978-3-642-54013-4 26[29] Hawblitzel, C., Howell, J., Kapritsos, M., Lorch, J.R., Parno, B., Roberts,M.L., Setty, S., Zill, B.: IronFleet: proving practical distributed systemscorrect. In: Symposium on Operating Systems Principles (SOSP). pp. 1–17.ACM (2015). https://doi.org/10.1145/2815400.2815428[30] Heule, S., Kassios, I.T., M¨uller, P., Summers, A.J.: Verification condition gen-eration for permission logics with abstract predicates and abstraction func-tions. In: European Conference on Object-Oriented Programming (ECOOP).pp. 451–476. Springer (2013). https://doi.org/10.1007/978-3-642-39038-8 19[31] Heule, S., Leino, K.R.M., M¨uller, P., Summers, A.J.: Abstract read per-missions: Fractional permissions without the fractions. In: Conference onVerification, Model Checking, and Abstract Interpretation (VMCAI). pp.315–334 (2013). https://doi.org/10.1007/978-3-642-35873-9 20[32] Kahsai, T., Kersten, R., R¨ummer, P., Sch¨af, M.: Quantified heap invariantsfor object-oriented programs. In: Conference on Logic for ProgrammingArtificial Intelligence and Reasoning (LPAR). pp. 368–384 (2017)[33] Kahsai, T., R¨ummer, P., Sanchez, H., Sch¨af, M.: JayHorn: A framework forverifying Java programs. In: Conference on Computer Aided Verification(CAV). pp. 352–358. Springer (2016). https://doi.org/10.1007/978-3-319-41528-4 19[34] Kashyap, V., Dewey, K., Kuefner, E.A., Wagner, J., Gibbons, K., Sarracino,J., Wiedermann, B., Hardekopf, B.: JSAI: a static analysis platform forJavaScript. In: Conference on Foundations of Software Engineering (FSE).pp. 121–132 (2014). https://doi.org/10.1145/2635868.2635904[35] Kawaguchi, M., Rondon, P., Jhala, R.: Type-based data structure verification.In: Conference on Programming Language Design and Implementation(PLDI). pp. 304–315 (2009). https://doi.org/10.1145/1542476.1542510[36] Kloos, J., Majumdar, R., Vafeiadis, V.: Asynchronous liquid separationtypes. In: European Conference on Object-Oriented Programming (ECOOP).pp. 396–420. Schloss Dagstuhl-Leibniz-Zentrum fuer Informatik (2015).https://doi.org/10.4230/LIPIcs.ECOOP.2015.396[37] Komuravelli, A., Gurfinkel, A., Chaki, S., Clarke, E.M.: Automatic ab-straction in SMT-based unbounded software model checking. In: Confer-ence on Computer Aided Verification (CAV). pp. 846–862. Springer (2013).https://doi.org/10.1007/978-3-642-39799-8 59 onSORT : Context- and Flow-Sensitive Ownership Refinement Types 29 [38] Leino, K.R.M.: Dafny: An automatic program verifier for functional correct-ness. In: Conference on Logic for Programming Artificial Intelligence and Rea-soning (LPAR). pp. 348–370. Springer (2010). https://doi.org/10.1007/978-3-642-17511-4 20[39] Leino, K.R.M., M¨uller, P., Smans, J.: Deadlock-free channels and locks. In:European Symposium on Programming (ESOP). pp. 407–426. Springer-Verlag (2010). https://doi.org/10.1007/978-3-642-11957-6 22[40] Matsushita, Y., Tsukada, T., Kobayashi, N.: RustHorn: CHC-based verifica-tion for Rust programs. In: European Symposium on Programming (ESOP).Springer (2020)[41] Milanova, A., Rountev, A., Ryder, B.G.: Parameterized object sen-sitivity for points-to analysis for Java. ACM Transactions on Soft-ware Engineering and Methodology (TOSEM) (1), 1–41 (2005).https://doi.org/10.1145/1044834.1044835[42] M¨uller, P., Schwerhoff, M., Summers, A.J.: Viper: A verification infrastruc-ture for permission-based reasoning. In: Conference on Verification, ModelChecking, and Abstract Interpretation (VMCAI). pp. 41–62. Springer-Verlag(2016). https://doi.org/10.1007/978-3-662-49122-5 2[43] Pierce, B.C.: Types and programming languages. MIT press (2002)[44] Protzenko, J., Zinzindohou´e, J.K., Rastogi, A., Ramananandro, T., Wang,P., Zanella-B´eguelin, S., Delignat-Lavaud, A., Hrit¸cu, C., Bhargavan, K.,Fournet, C., Swamy, N.: Verified low-level programming embedded in F*.Proceedings of the ACM on Programming Languages (ICFP), 17:1–17:29(2017). https://doi.org/10.1145/3110261[45] Reynolds, J.C.: Separation logic: A logic for shared mutable data structures.In: Symposium on Logic in Computer Science (LICS). pp. 55–74. IEEE(2002). https://doi.org/10.1109/LICS.2002.1029817[46] Rondon, P., Kawaguchi, M., Jhala, R.: Low-level liquid types. In: Symposiumon Principles of Programming Languages (POPL). pp. 131–144 (2010).https://doi.org/10.1145/1706299.1706316[47] Rondon, P.M., Kawaguci, M., Jhala, R.: Liquid types. In: Conference onProgramming Language Design and Implementation (PLDI). pp. 159–169(2008). https://doi.org/10.1145/1375581.1375602[48] R¨ummer, P., Hojjat, H., Kuncak, V.: Disjunctive interpolants for Horn-clause verification. In: Conference on Computer Aided Verification (CAV).pp. 347–363. Springer (2013). https://doi.org/10.1007/978-3-642-39799-8 24[49] Sharir, M., Pnueli, A.: Two approaches to interprocedural data flow analysis.In: Muchnick, S.S., Jones, N.D. (eds.) Program Flow Analysis: Theory andApplications, chap. 7, pp. 189–223. Prentice Hall (1981)[50] Shivers, O.: Control-flow analysis of higher-order languages. Ph.D. thesis,Carnegie Mellon University (1991)[51] Smaragdakis, Y., Bravenboer, M., Lhot´ak, O.: Pick your con-texts well: Understanding object-sensitivity. In: Symposium onPrinciples of Programming Languages (POPL). pp. 17–30 (2011).https://doi.org/10.1145/1926385.1926390 [52] Smith, F., Walker, D., Morrisett, G.: Alias types. In: EuropeanSymposium on Programming (ESOP). pp. 366–381. Springer (2000).https://doi.org/10.1007/3-540-46425-5 24[53] Sp¨ath, J., Ali, K., Bodden, E.: Context-, flow-, and field-sensitivedata-flow analysis using synchronized pushdown systems. Proceedingsof the ACM on Programming Languages (POPL), 48:1–48:29 (2019).https://doi.org/10.1145/3290361[54] Sp¨ath, J., Nguyen Quang Do, L., Ali, K., Bodden, E.: Boomerang:Demand-driven flow-and context-sensitive pointer analysis for Java. In:European Conference on Object-Oriented Programming (ECOOP). pp.22:1–22:26. Schloss Dagstuhl-Leibniz-Zentrum fuer Informatik (2016).https://doi.org/10.4230/LIPIcs.ECOOP.2016.22[55] Suenaga, K., Fukuda, R., Igarashi, A.: Type-based safe resource dealloca-tion for shared-memory concurrency. In: Conference on Object OrientedProgramming Systems Languages and Applications (OOPSLA). pp. 1–20(2012). https://doi.org/10.1145/2384616.2384618[56] Suenaga, K., Kobayashi, N.: Fractional ownerships for safe memory deal-location. In: Asian Symposium on Programming Languages and Systems(APLAS). pp. 128–143. Springer (2009). https://doi.org/10.1007/978-3-642-10672-9 11[57] Swamy, N., Hrit¸cu, C., Keller, C., Rastogi, A., Delignat-Lavaud, A., Forest,S., Bhargavan, K., Fournet, C., Strub, P.Y., Kohlweiss, M., Zinzindohou´e,J.K., Zanella-B´eguelin, S.: Dependent types and multi-monadic effects inF*. In: Symposium on Principles of Programming Languages (POPL). pp.256–270 (2016). https://doi.org/10.1145/2837614.2837655[58] Swamy, N., Weinberger, J., Schlesinger, C., Chen, J., Livshits, B.: Verifyinghigher-order programs with the Dijkstra monad. In: Conference on Program-ming Language Design and Implementation (PLDI). pp. 387–398 (2013).https://doi.org/10.1145/2491956.2491978[59] Terauchi, T.: Checking race freedom via linear programming. In: Conferenceon Programming Language Design and Implementation (PLDI). pp. 1–10(2008). https://doi.org/10.1145/1375581.1375583[60] Unno, H., Kobayashi, N.: Dependent type inference with interpolants. In:Conference on Principles and Practice of Declarative Programming (PPDP).pp. 277–288. ACM (2009). https://doi.org/10.1145/1599410.1599445[61] Vazou, N., Rondon, P.M., Jhala, R.: Abstract refinement types. In: Euro-pean Symposium on Programming (ESOP). pp. 209–228. Springer (2013).https://doi.org/10.1007/978-3-642-37036-6 13[62] Vazou, N., Seidel, E.L., Jhala, R., Vytiniotis, D., Peyton-Jones, S.: Refine-ment types for Haskell. In: International Conference on Functional Program-ming (ICFP). pp. 269–282 (2014). https://doi.org/10.1145/2628136.2628161[63] Wells, J.B., Dimock, A., Muller, R., Turbak, F.: A calculus with polymorphicand polyvariant flow types. Journal of Functional Programming (3), 183–227 (2002). https://doi.org/10.1017/S0956796801004245 onSORT : Context- and Flow-Sensitive Ownership Refinement Types 31 [64] Xi, H., Pfenning, F.: Dependent types in practical programming. In: Sympo-sium on Principles of Programming Languages (POPL). pp. 214–227. ACM(1999). https://doi.org/10.1145/292540.292560[65] Zave, P.: Using lightweight modeling to understand Chord. ACMSIGCOMM Computer Communication Review (2), 49–57 (2012).https://doi.org/10.1145/2185376.2185383[66] Zhu, H., Jagannathan, S.: Compositional and lightweight dependenttype inference for ML. In: Conference on Verification, Model Check-ing, and Abstract Interpretation (VMCAI). pp. 295–314. Springer (2013).https://doi.org/10.1007/978-3-642-35873-9 19 Open Access
This chapter is licensed under the terms of the Creative CommonsAttribution 4.0 International License (http://creativecommons.org/licenses/by/4.0/),which permits use, sharing, adaptation, distribution and reproduction in any medium orformat, as long as you give appropriate credit to the original author(s) and the source,provide a link to the Creative Commons license and indicate if changes were made.The images or other third party material in this chapter are included in the chapter’sCreative Commons license, unless indicated otherwise in a credit line to the material. Ifmaterial is not included in the chapter’s Creative Commons license and your intendeduse is not permitted by statutory regulation or exceeds the permitted use, you will needto obtain permission directly from the copyright holder.2 J. Toman et al. Θ | [] : τ ⇒ Γ | L (cid:96) ectx E : τ (cid:48) ⇒ Γ (cid:48) Θ | L | Γ (cid:48) (cid:96) e : τ (cid:48)(cid:48) ⇒ Γ (cid:48)(cid:48) Θ | [] : τ ⇒ Γ | L (cid:96) ectx E ; e : τ (cid:48)(cid:48) ⇒ Γ (cid:48)(cid:48) ( TE-Seq ) Θ | [] : τ ⇒ Γ | L (cid:96) ectx [] : τ ⇒ Γ ( TE-Hole ) Θ | [] : τ (cid:48) ⇒ Γ (cid:48) | L (cid:96) ectx E : τ (cid:48)(cid:48) ⇒ Γ (cid:48)(cid:48) Θ | L | Γ, x : τ (cid:96) e : τ (cid:48) ⇒ Γ (cid:48) x (cid:54)∈ dom ( Γ (cid:48) ) Θ | [] : τ ⇒ Γ | L (cid:96) ectx E [ let x = [] (cid:96) in e ] : τ (cid:48)(cid:48) ⇒ Γ (cid:48)(cid:48) ( TE-Stack )( E ; e )[ e (cid:48) ] = E [ e (cid:48) ] ; e [][ e (cid:48) ] = e (cid:48) E [ let y = [] (cid:96) in e ][ x ] = E [ let y = x in e ] Fig. 11.
Context typing and substitution
A Proof of Type Soundness (Theorem 1)
We first define a typing relation for machine configurations (cid:68) H , R , (cid:126)F , e (cid:69) as shownin Figure 12. The critical component of this typing relation is the consistencyrelation Cons . Intuitively,
Cons expresses that the current heap and registers areconsistent with the ownership and refinement information implied by Γ . We saytriple ( H , R , Γ ) is consistent , and write Cons ( H , R , Γ ). In the definitions for own we write { a (cid:55)→ r } to denote a function Addr → [0 ,
1] which returns r for a , and 0otherwise. We write ∅ to denote a constant function Addr → [0 ,
1] which alwaysreturns 0. We define the addition between two functions O , O : Addr → [0 , O + O )( a ) = O ( a ) + O ( a ). Finally, if a summation Σ has no summands,we take its result to be ∅ .The proof of Theorem 1 requires the following four key lemmas. These lemmasare stated with respect to some well-typed program (cid:104) D , e (cid:105) , i.e. (cid:96) (cid:104) D , e (cid:105) . Lemma 1. (cid:96) D conf (cid:104)∅ , ∅ , · , e (cid:105) Proof.
Trivial, taking Γ = • and by inversion on (cid:96) (cid:104) D , e (cid:105) . Lemma 2. (cid:96) D conf C implies C (cid:54) = AssertFail
Proof.
Simple proof by contradiction, as the
AssertFail is not well-typed.
Lemma 3. If (cid:96) D conf (cid:68) H , R , (cid:126)F , e (cid:69) and (cid:68) H , R , (cid:126)F , e (cid:69) −→ D C , then (cid:96) D conf C onSORT : Context- and Flow-Sensitive Ownership Refinement Types 33 (cid:126)(cid:96) = Trace ( (cid:126)F ) n = | (cid:126)(cid:96) | = | (cid:126)F | Θ (cid:96) D ∀ j ∈ { ..n } .(cid:126)(cid:96) j = tail n − j +1 ( (cid:126)(cid:96) ) Cons ( H , R , Γ ) ∀ i ∈ { ..n } .Θ | [] : τ i ⇒ Γ i | (cid:126)(cid:96) i (cid:96) ectx F i : τ i − ⇒ Γ i − (cid:126)F = F n : · · · : F : · Θ | (cid:126)(cid:96) | Γ (cid:96) e : τ n ⇒ Γ n (cid:96) D conf (cid:68) H , R , (cid:126)F , e (cid:69) (cid:96) D conf AliasFailTrace ( · ) = (cid:15) Trace ( E [ let x = [] (cid:96) in e ] : (cid:126)F ) = (cid:96) : Trace ( (cid:126)F ) Cons ( H , R , Γ ) def ⇐⇒ SAT ( H , R , Γ ) ∧ ∀ a ∈ dom ( H ) . Own ( H , R , Γ )( a ) ≤ SAT ( H , R , Γ ) def ⇐⇒ ∀ x ∈ dom ( Γ ) . x ∈ dom ( R ) ∧ SATv ( H , R , R ( x ) , Γ ( x )) SATv ( H , R , v, τ ) def ⇐⇒ (cid:40) v ∈ Z ∧ [ R ] [ v/ν ] ϕ τ = { ν : int | ϕ } a ∈ dom ( H ) ∧ SATv ( H , R , H ( a ) , τ (cid:48) ) τ = τ (cid:48) ref r ∧ v = a [ ∅ ] ϕ = ϕ [ R { y (cid:55)→ n } ] ϕ = [ R ] [ n/ y ] ϕ [ R { y (cid:55)→ a } ] ϕ = [ R ] ϕ Own ( H , R , Γ ) = Σ x ∈ dom ( Γ ) own ( H , R ( x ) , Γ ( x )) own ( H , v , τ ) = (cid:40) { a (cid:55)→ r } + own ( H , H ( a ) , τ (cid:48) ) v = a ∧ a ∈ dom ( H ) ∧ τ = τ (cid:48) ref r ∅ o.w. Fig. 12.
Machine state typing4 J. Toman et al.
Lemma 4. If (cid:96) D conf C , then, one of the following conditions hold:1. ∃ C (cid:48) , C −→ D C (cid:48) , or2. C = AssertFail , or3. C = (cid:104) H , R , · , x (cid:105) Lemmas 3 and 4 are the heart of proof effort, we give their proofs in Appendices Cand D respectively.We can now prove Theorem 1:
Proof (Theorem 1: Soundness).
From Lemmas 1 and 3 and an inductive argument,any configuration reachable from the initial state must be well-typed. Then,by Lemma 2 every configuration reachable from the initial state cannot be
AssertFail , i.e., a well-typed program never experiences an assertion failure.This completes the first part of the proof.To prove the second portion of the theorem, it suffices to show that anyconfiguration reachable from the initial state can step or is a final configuration.Again from Lemmas 1 and 3 and a simple inductive argument, we must havethat for any state C such that (cid:104)∅ , ∅ , · , e (cid:105) −→ ∗ D C (cid:96) D conf C . Then by Lemma 4 wehave the configuration may step or is one of the final configurations.The remainder of this appendix proves Lemmas 3 and 4. We introduce someauxiliary definitions and lemmas in Appendix B, give the proof of Lemma 3 inAppendix C, and prove Lemma 4 in Appendix D. B Auxiliary Lemmas and Definitions
The well-formedness rules omitted from the main paper are found in Figure 13.We write
L (cid:96) WF τ ⇒ Γ as shorthand for L (cid:96) WF Γ and L | Γ (cid:96) WF τ .We first prove that the subtyping relations are transitive. Lemma 5.
1. If Γ ≤ Γ (cid:48) then | = (cid:74) Γ (cid:75) = ⇒ (cid:74) Γ (cid:48) (cid:75) .2. If Γ (cid:96) τ ≤ τ and Γ (cid:96) τ ≤ τ , then Γ (cid:96) τ ≤ τ
3. If Γ ≤ Γ (cid:48) and Γ (cid:48) (cid:96) τ ≤ τ , then Γ (cid:96) τ ≤ τ
4. If Γ ≤ Γ (cid:48) , Γ (cid:96) τ ≤ τ , and Γ (cid:48) (cid:96) τ ≤ τ , then Γ (cid:96) τ ≤ τ .5. If Γ ≤ Γ (cid:48) and Γ (cid:48) ≤ Γ (cid:48)(cid:48) , then Γ ≤ Γ (cid:48)(cid:48) .Proof.
1. It suffices to show that | = (cid:74) Γ (cid:75) = ⇒ [ x / ν ] ϕ (cid:48) for any x ∈ dom ( Γ (cid:48) ) where Γ (cid:48) ( x ) = { ν : int | ϕ (cid:48) } . From Γ ≤ Γ (cid:48) we have | = (cid:74) Γ (cid:75) ∧ ϕ = ⇒ ϕ (cid:48) where Γ ( x ) = { ν : int | ϕ } . We must then have | = (cid:74) Γ (cid:75) ∧ [ x / ν ] ϕ = ⇒ [ x / ν ] ϕ (cid:48) . From thedefinition of (cid:74) Γ (cid:75) we have (cid:74) Γ (cid:75) ∧ [ x / ν ] ϕ ⇐⇒ (cid:74) Γ (cid:75) , giving the desired result. onSORT : Context- and Flow-Sensitive Ownership Refinement Types 35 ∀ x ∈ dom ( Γ ) . L | Γ (cid:96) WF Γ ( x ) L (cid:96) WF Γ ( WF-Env ) L | Γ (cid:96) WF ϕ L | Γ (cid:96) WF { ν : int | ϕ } ( WF-Int ) L | Γ (cid:96) WF τ L | Γ (cid:96) WF τ ref r ( WF-Ref ) ∀ x ∈ FPV ( ϕ ) \ { ν } .Γ ( x ) = { ν : int | } FCV ( ϕ ) ⊆ CV ( L ) L | Γ (cid:96) WF ϕ ( WF-Phi ) L | Γ (cid:96) WF τ L (cid:96) WF Γ L (cid:96) WF τ ⇒ Γ ( WF-Result ) λ (cid:96) WF x : τ , . . . , x n : τ n λ (cid:96) WF τ ⇒ x : τ (cid:48) , . . . , x n : τ (cid:48) n (cid:96) WF ∀ λ. (cid:104) x : τ , . . . , x n : τ n (cid:105) → (cid:10) x : τ (cid:48) , . . . , x n : τ (cid:48) n | τ (cid:11) ( WF-FunType ) ∀ f ∈ dom ( Θ ) . (cid:96) WF Θ ( f ) (cid:96) WF Θ ( WF-FunEnv )Free Ctxt Vars
FCV ( ϕ ∨ ϕ ) = FCV ( ϕ ) ∪ FCV ( ϕ ) FCV ( ¬ ϕ ) = FCV ( ϕ ) FCV ( (cid:98) v = (cid:98) v ) = FCV ( φ ( (cid:98) v , .. , (cid:98) v n )) = ∅ FCV ( (cid:126)(cid:96) (cid:22) C ) = FCV ( C ) FCV ( (cid:96) : C ) = FCV ( C ) FCV ( L ) = CV ( L )Ctxt Vars CV ( (cid:126)(cid:96) ) = ∅ CV ( λ ) = { λ } Fig. 13.
Well-formedness of types and environments.
2. By induction on Γ (cid:96) τ ≤ τ . We only consider the base case where τ = { ν : int | ϕ } and τ = { ν : int | ϕ } , the case for reference types follows fromthe induction hypothesis. By further inversion on Γ (cid:96) τ ≤ τ we thereforehave: τ = { ν : int | ϕ }| = (cid:74) Γ (cid:75) ∧ ϕ = ⇒ ϕ | = (cid:74) Γ (cid:75) ∧ ϕ = ⇒ ϕ From which it is immediate that we must have | = (cid:74) Γ (cid:75) ∧ ϕ = ⇒ ϕ , whereby S-Int gives Γ (cid:96) τ ≤ τ .3. By induction on Γ (cid:48) (cid:96) τ ≤ τ . The case for reference types is immediate fromthe inductive hypothesis, we focus on the base case where τ = { ν : int | ϕ } and τ = { ν : int | ϕ } , and where | = (cid:74) Γ (cid:48) (cid:75) ∧ ϕ = ⇒ ϕ . From Γ ≤ Γ (cid:48) and Item 1 above, we have | = (cid:74) Γ (cid:75) = ⇒ (cid:74) Γ (cid:48) (cid:75) from which we can derive (cid:74) Γ (cid:75) ∧ ϕ = ⇒ ϕ , i.e., Γ (cid:96) τ ≤ τ .4. Immediate from Items 2 and 3.5. Immediate corollary of Item 4. Definition 1.
A value v reaches an integer with n dereferences in heap H whenit is in the relation H (cid:96) v ⇓ n defined as the smallest relation closed under thefollowing rules:1. If v ∈ Z then H (cid:96) v ⇓
2. If H (cid:96) v ⇓ n and H ( a ) = v then H (cid:96) a ⇓ n + 1 We will write H (cid:96) v ⇓ | τ | to indicate a value v is shape consistent with τ in heapH , where | τ | is the number of reference constructors in the type τ . We also prove a standard inversion lemma to handle the fact our typing rulesare not syntax directed.
Lemma 6 (Inversion). If Θ | L | Γ (cid:96) e : τ ⇒ Γ (cid:48) , then there exists some Γ p , τ p , and Γ (cid:48) p such that Γ ≤ Γ p , (cid:126)(cid:96) (cid:96) WF Γ p , Γ (cid:48) p , τ p ≤ Γ (cid:48) , τ , and:1. If e = x then Γ p ( x ) = τ p + τ (cid:48) , Γ (cid:48) p = Γ p [ x ← (cid:45) τ (cid:48) ] .2. If e = let x = y in e, then Θ | L | Γ p [ y ← (cid:45) τ ∧ y y = τ x ] , x : ( τ ∧ x x = τ y ) (cid:96) e : τ p ⇒ Γ (cid:48) p and x (cid:54)∈ dom ( Γ (cid:48) p ) where Γ p ( y ) = τ + τ .3. If e = let x = n in e then Θ | L | Γ p , x : { ν : int | ν = n } (cid:96) e : τ p ⇒ Γ (cid:48) p andx (cid:54)∈ dom ( Γ (cid:48) p ) .4. If e = ifz x then e else e then: – Γ p ( x ) = { ν : int | ϕ } – Θ | L | Γ p [ x ← (cid:45) { ν : int | ϕ ∧ ν = 0 } ] (cid:96) e : τ p ⇒ Γ (cid:48) p – Θ | L | Γ p [ x ← (cid:45) { ν : int | ϕ ∧ ν (cid:54) = 0 } ] (cid:96) e : τ p ⇒ Γ (cid:48) p
5. If e = let x = mkref y in e, then Γ p ( y ) = τ + τ , Θ | L | Γ [ y ← (cid:45) τ ] , x :( τ ∧ x x = τ y ) ref (cid:96) e : τ ⇒ Γ (cid:48) p , and x (cid:54)∈ dom ( Γ (cid:48) p )
6. If e = let x = ∗ y in e, then: – Γ p ( y ) = τ + τ ref r – Θ | L | Γ p [ y ← (cid:45) τ (cid:48)(cid:48) ref r ] , x : τ (cid:96) e : τ p ⇒ Γ (cid:48) p – x (cid:54)∈ dom ( Γ (cid:48) p ) – τ (cid:48)(cid:48) = (cid:40) ( τ ∧ y y = τ x ) r > τ r = 0
7. If e = let x = f (cid:96) ( y , . . . , y n ) in e then: – Γ p ( y i ) = σ α σ x τ i for each i ∈ { , . . . , n } – Θ | L | Γ p [ y i ← (cid:45) σ α σ x τ (cid:48) i ] , x : σ α σ x τ (cid:96) e : τ p ⇒ Γ (cid:48) p – Θ ( f ) = ∀ λ. (cid:104) x : τ , . . . , x n : τ n (cid:105) → (cid:104) x : τ (cid:48) , . . . , x n : τ (cid:48) n | τ (cid:105) – σ α = [ (cid:96) : L /λ ] – σ x = [ y / x ] · · · [ y n / x n ] – x (cid:54)∈ dom ( Γ (cid:48) p )
8. If e = y : = x ; e then: – Γ p ( x ) = τ + τ – Γ p ( y ) = τ (cid:48) ref – Θ | L | Γ p [ x ← (cid:45) τ ][ y ← (cid:45) ( τ ∧ y y = τ x ) ref ] (cid:96) e : τ p ⇒ Γ (cid:48) p – The shapes of τ (cid:48) and τ are similar, i.e, | τ (cid:48) | = | τ | .9. If e = alias ( x = y ) ; e then there exist some τ , τ , τ (cid:48) , τ (cid:48) , r , r , r (cid:48) , r (cid:48) suchthat: – τ ref r + τ ref r ≈ τ (cid:48) ref r (cid:48) + τ (cid:48) ref r (cid:48) – Γ p ( x ) = τ ref r and Γ p ( y ) = τ ref r – Θ | L | Γ [ x ← (cid:45) τ (cid:48) ref r (cid:48) ][ y ← (cid:45) τ (cid:48) ref r (cid:48) ] (cid:96) e : τ p ⇒ Γ (cid:48) p
10. If e = alias ( x = ∗ y ) ; e then there exist some τ , τ , τ (cid:48) , τ (cid:48) , r , r , r (cid:48) , r (cid:48) , r ,such that: – τ ref r + τ ref r ≈ τ (cid:48) ref r (cid:48) + τ (cid:48) ref r (cid:48) – Γ p ( x ) = τ ref r and Γ p ( y ) = ( τ ref r ) ref r onSORT : Context- and Flow-Sensitive Ownership Refinement Types 37 – Θ | L | Γ [ x ← (cid:45) τ (cid:48) ref r (cid:48) ][ y ← (cid:45) ( τ (cid:48) ref r (cid:48) ) ref r ] (cid:96) e : τ p ⇒ Γ (cid:48) p
11. If e = e ; e then Θ | L | Γ p (cid:96) e : τ ⇒ Γ and Θ | L | Γ (cid:96) e : τ p ⇒ Γ (cid:48) p
12. If e = x ; e (cid:48) then Θ | L | Γ p [ x : τ (cid:48) + τ ] (cid:96) x : τ ⇒ Γ p [ x ← (cid:45) τ ] and Θ | L | Γ p [ x ← (cid:45) τ ] (cid:96) e (cid:48) : τ p ⇒ Γ (cid:48) p
13. If e = assert ( ϕ ) ; e then Γ p | = ϕ and Θ | L | Γ p (cid:96) e : τ p ⇒ Γ (cid:48) p Proof.
By straightforward induction on the typing relation and the transitivityof the subtyping relation Lemma 5.The only case of note is the case for e = x ; e . If the subderivation for x has applications of T-Sub then the subtypings on the output environment canbe pushed into application subtyping on input environments when typing e (cid:48) .Similarly, any input subtypings on the input environment of the derivation of x can be pushed into T-Sub rules such that Γ ≤ Γ p [ x : τ (cid:48) + τ ].Lemmas 7 and 8 prove some standard properties of execution contexts: anydecomposition of a well-typed expression into a execution context and redex canbe well-typed, and substituting a well-typed expression matching a context’s holetype yields a well-typed expression Lemma 7.
For any E and e (cid:48) such that E [ e (cid:48) ] = e where Θ | L | Γ (cid:96) e : τ ⇒ Γ (cid:48) there exists some τ , Γ such that Θ | [] : τ ⇒ Γ | L (cid:96) ectx E : τ ⇒ Γ (cid:48) and Θ | L | Γ (cid:96) e (cid:48) : τ ⇒ Γ .Proof. By induction on the structure of E . Case E = [] : Trivial, by taking τ = τ and Γ = Γ (cid:48) . Case E = E (cid:48) ; e (cid:48)(cid:48) : Then E [ e (cid:48) ] = E (cid:48) [ e (cid:48) ] ; e (cid:48)(cid:48) = e . By Lemma 6 we have Θ | L | Γ p (cid:96) E (cid:48) [ e (cid:48) ] : τ ⇒ Γ Θ | L | Γ (cid:96) e (cid:48)(cid:48) : τ p ⇒ Γ (cid:48) p Γ ≤ Γ p Γ (cid:48) p , τ p ≤ Γ (cid:48) , τ for some Γ p , Γ (cid:48) p , and τ p .By the induction hypothesis we then have Θ | L | Γ p (cid:96) e (cid:48) : τ ⇒ Γ and Θ | [] : τ ⇒ Γ | L (cid:96) ectx E (cid:48) : τ ⇒ Γ . for some τ and Γ .Next, as Γ (cid:48) p , τ p ≤ Γ (cid:48) , τ by an application of T-Sub , we have Θ | L | Γ (cid:96) e (cid:48)(cid:48) : τ ⇒ Γ (cid:48) . By TE-Seq , we therefore have: Θ | [] : τ ⇒ Γ | L (cid:96) ectx E (cid:48) ; e (cid:48)(cid:48) : τ ⇒ Γ (cid:48) .Finally, from Γ ≤ Γ p and Θ | L | Γ p (cid:96) e (cid:48) : τ ⇒ Γ , and application of T-Sub ,we have Θ | L | Γ (cid:96) e (cid:48) : τ ⇒ Γ . Lemma 8. If Θ | [] : τ ⇒ Γ (cid:48) | L (cid:96) ectx E : τ (cid:48)(cid:48) ⇒ Γ (cid:48)(cid:48) and Θ | L | Γ (cid:96) e : τ ⇒ Γ (cid:48) for some Γ , then Θ | L | Γ (cid:96) E [ e ] : τ (cid:48)(cid:48) ⇒ Γ (cid:48)(cid:48) .Proof. By induction on the typing derivation of E . Case
TE-Seq : E = E (cid:48) ; e (cid:48) E [ e ] = E (cid:48) [ e ] ; e (cid:48) Θ | [] : τ ⇒ Γ (cid:48) | L (cid:96) ectx E (cid:48) : τ ⇒ Γ Θ | L | Γ (cid:96) e (cid:48) : τ (cid:48)(cid:48) ⇒ Γ (cid:48)(cid:48) By the induction hypothesis we have Θ | L | Γ (cid:96) E (cid:48) [ e ] : τ ⇒ Γ . We then haveour result via an application of T-Seq . Case
TE-Hole : Trivial, as τ = τ (cid:48)(cid:48) and Γ (cid:48) = Γ (cid:48)(cid:48) and E [ e ] = e . Lemma 9 (Context Variable Substitution).
1. If τ = τ + τ then [ L /λ ] τ = [ L /λ ] τ + [ L /λ ] τ
2. For any (cid:126)(cid:96) :(a) If λ (cid:96) WF Γ then (cid:126)(cid:96) (cid:96) WF [ (cid:126)(cid:96)/λ ] Γ (b) If λ | Γ (cid:96) WF τ then (cid:126)(cid:96) | [ (cid:126)(cid:96)/λ ] Γ (cid:96) WF [ (cid:126)(cid:96)/λ ] τ (c) If λ (cid:96) WF τ ⇒ Γ then (cid:126)(cid:96) (cid:96) WF [ (cid:126)(cid:96)/λ ] τ ⇒ [ (cid:126)(cid:96)/λ ] Γ
3. For any Γ , τ , τ , λ and (cid:126)(cid:96) , If Γ (cid:96) τ ≤ τ , then [ (cid:126)(cid:96)/λ ] Γ (cid:96) [ (cid:126)(cid:96)/λ ] τ ≤ [ (cid:126)(cid:96)/λ ] τ
4. If Γ | = ϕ where λ (cid:54)∈ FCV ( ϕ ) then [ (cid:126)(cid:96)/λ ] Γ | = ϕ
5. If Θ | λ | Γ (cid:96) e : τ ⇒ Γ (cid:48) then Θ | (cid:126)(cid:96) | [ (cid:126)(cid:96)/λ ] Γ (cid:96) e : [ (cid:126)(cid:96)/λ ] τ ⇒ [ (cid:126)(cid:96)/λ ] Γ (cid:48) Proof.
1. By straightforward induction on the definition of τ + τ = τ .2. Observe that any substitution of context variables cannot change simpletypes within Γ and thus all types and refinements remain well-formed withrespect to integer variables in Γ . It thus suffices to show that FCV ([ (cid:126)(cid:96)/λ ] ϕ ) ⊆ CV ( (cid:126)(cid:96) ) = ∅ for any refinement ϕ appearing in τ or a type in Γ . By theassumed well-formedness of τ with respect to context variable λ (resp. Γ ),after substitution all free context variables in τ (resp. the types in Γ ) willbe replaced with (cid:126)(cid:96) . Thus, post-substitution no free context variables appearin the refinement of [ (cid:126)(cid:96)/λ ] τ (resp. refinements of types in [ (cid:126)(cid:96)/λ ] Γ ), triviallysatisfying our requirements.3. If λ does not appear free in τ , τ or Γ , then the result trivially holds. Letus then assume λ appears free. We prove the result by induction on thesubtyping derivation. Case
S-Ref : τ = τ (cid:48) ref r τ = τ (cid:48) ref r [ (cid:126)(cid:96)/λ ] τ = ([ (cid:126)(cid:96)/λ ] τ (cid:48) ) ref r [ (cid:126)(cid:96)/λ ] τ = ([ (cid:126)(cid:96)/λ ] τ (cid:48) ) ref r Γ (cid:96) τ (cid:48) ≤ τ (cid:48) r ≤ r We must show that [ (cid:126)(cid:96)/λ ] Γ (cid:96) [ (cid:126)(cid:96)/λ ] τ (cid:48) ≤ [ (cid:126)(cid:96)/λ ] τ (cid:48) which holds immediately fromthe induction hypothesis. onSORT : Context- and Flow-Sensitive Ownership Refinement Types 39 Case
S-Int : τ = { ν : int | ϕ } τ = { ν : int | ϕ } [ (cid:126)(cid:96)/λ ] τ = (cid:110) ν : int | [ (cid:126)(cid:96)/λ ] ϕ (cid:111) [ (cid:126)(cid:96)/λ ] τ = (cid:110) ν : int | [ (cid:126)(cid:96)/λ ] ϕ (cid:111) Γ | = ϕ = ⇒ ϕ We must show that [ (cid:126)(cid:96)/λ ] Γ | = [ (cid:126)(cid:96)/λ ] ϕ = ⇒ [ (cid:126)(cid:96)/λ ] ϕ , i.e. | = (cid:114) [ (cid:126)(cid:96)/λ ] Γ (cid:122) ∧ [ (cid:126)(cid:96)/λ ] ϕ = ⇒ [ (cid:126)(cid:96)/λ ] ϕ . From our assumption that Γ | = ϕ = ⇒ ϕ we havethat | = (cid:74) Γ (cid:75) ∧ ϕ = ⇒ ϕ is valid, whereby the formula (cid:74) Γ (cid:75) ∧ ϕ = ⇒ ϕ is truefor any possible concrete valuation of the free context variable λ . As [ (cid:126)(cid:96)/λ ] (cid:74) Γ (cid:75) is equivalent to (cid:114) [ (cid:126)(cid:96)/λ ] Γ (cid:122) we have the formula (cid:114) [ (cid:126)(cid:96)/λ ] Γ (cid:122) ∧ [ (cid:126)(cid:96)/λ ] ϕ = ⇒ [ (cid:126)(cid:96)/λ ] ϕ must also be valid.4. If λ does not appear free in (cid:74) Γ (cid:75) , then the result trivially holds. Otherwise | = (cid:74) Γ (cid:75) = ⇒ ϕ holds for any concrete valuation of the free context variable λ .Then the formula | = (cid:114) [ (cid:126)(cid:96)/λ ] Γ (cid:122) = ⇒ ϕ must be valid from the equivalence of[ (cid:126)(cid:96)/λ ] (cid:74) Γ (cid:75) and (cid:114) [ (cid:126)(cid:96)/λ ] Γ (cid:122) .5. By induction on the typing derivation Θ | λ | Γ (cid:96) e : τ ⇒ Γ (cid:48) . In every case,that (cid:126)(cid:96) (cid:96) WF [ (cid:126)(cid:96)/λ ] τ ⇒ [ (cid:126)(cid:96)/λ ] Γ (cid:48) and (cid:126)(cid:96) (cid:96) WF [ (cid:126)(cid:96)/λ ] Γ holds from Item 2. Case
T-Var : e = x τ = τ Γ = Γ [ x : τ + τ ] Γ (cid:48) = Γ [ x ← (cid:45) τ ]By application of Item 1. Case
T-LetInt : e = let x = n in e (cid:48) Θ | λ | Γ, x : { ν : int | ν = n } (cid:96) e (cid:48) : τ ⇒ Γ (cid:48) x (cid:54)∈ dom ( Γ (cid:48) )The induction hypothesis gives Θ | (cid:126)(cid:96) | [ (cid:126)(cid:96)/λ ] Γ, x : { ν : int | ν = n } (cid:96) e : [ (cid:126)(cid:96)/λ ] τ ⇒ [ (cid:126)(cid:96)/λ ] Γ (cid:48) We conclude Θ | (cid:126)(cid:96) | [ (cid:126)(cid:96)/λ ] Γ (cid:96) let x = n in e : [ (cid:126)(cid:96)/λ ] τ ⇒ [ (cid:126)(cid:96)/λ ] Γ (cid:48) as required. Case
T-Let : e = let x = y in e (cid:48) x (cid:54)∈ dom ( Γ (cid:48) ) Θ | λ | Γ (cid:96) e (cid:48) : τ ⇒ Γ (cid:48) Γ = Γ [ y ← (cid:45) ( τ ∧ y y = τ x )] , x : ( τ ∧ x x = τ y ) Γ ( y ) = y : τ + τ By Item 1, ([ (cid:126)(cid:96)/λ ] Γ )( y ) = [ (cid:126)(cid:96)/λ ] ( τ + τ ) = ([ (cid:126)(cid:96)/λ ] τ + [ (cid:126)(cid:96)/λ ] τ ). We must thenshow that Θ | (cid:126)(cid:96) | Γ (cid:48) (cid:96) e (cid:48) : [ (cid:126)(cid:96)/λ ] τ ⇒ [ (cid:126)(cid:96)/λ ] Γ (cid:48) where Γ (cid:48) = ([ (cid:126)(cid:96)/λ ] Γ )[ y ← (cid:45) [ (cid:126)(cid:96)/λ ] τ ∧ y y = x ] , x : ([ (cid:126)(cid:96)/λ ] τ ∧ x x = y )As Γ (cid:48) = [ (cid:126)(cid:96)/λ ] Γ the induction hypothesis gives the required typing judgment. Case
T-If,T-Seq : By trivial application of the inductive hypothesis.
Case
T-MkRef,T-Deref : By reasoning similar to
T-Let . Case
T-Call : e = let x = f (cid:96) ( y , . . . , y n ) in e (cid:48) σ x = [ y / x ] · · · [ y n / x n ] σ α = [ (cid:96) : λ/λ (cid:48) ] Θ | λ | Γ (cid:96) e (cid:48) : τ ⇒ Γ (cid:48) y (cid:54)∈ dom ( Γ (cid:48) ) Θ ( f ) = ∀ λ (cid:48) . (cid:104) x : τ , . . . , x n : τ n (cid:105) → (cid:104) x : τ (cid:48) , . . . , x n : τ (cid:48) n | τ (cid:48) (cid:105) Γ = Γ [ y i ← (cid:45) σ α σ x τ (cid:48) i ] , x : σ α σ x τ (cid:48) We must first show that for σ (cid:48) α = [ (cid:96) : (cid:126)(cid:96)/λ (cid:48) ]: Θ | (cid:126)(cid:96) | Γ (cid:96) e (cid:48) : [ (cid:126)(cid:96)/λ ] τ ⇒ [ (cid:126)(cid:96)/λ ] Γ (cid:48) where Γ = ([ (cid:126)(cid:96)/λ ] Γ )[ y i ← (cid:45) σ (cid:48) α σ x τ (cid:48) i ] , x : σ (cid:48) α σ x τ (cid:48) .We first observe that Γ = [ (cid:126)(cid:96)/λ ] Γ (this follows from the equivalence of[ (cid:126)(cid:96)/λ ] [ (cid:96) : λ/λ (cid:48) ] and [ (cid:96) : (cid:126)(cid:96)/λ (cid:48) ]) whereby the induction hypothesis gives therequired typing derivation.We must also show that ∀ i ∈ { ..n } . ([ (cid:96) : (cid:126)(cid:96)/λ ] Γ )( y i ) = σ (cid:48) α σ x τ i . From theassumed well-typing of the term under λ we have that ∀ i ∈ { ..n } .Γ ( y i ) = σ α σ x τ i . Recall that σ (cid:48) α is equivalent to [ (cid:126)(cid:96)/λ ] σ α , whereby we have [ (cid:126)(cid:96)/λ ] Γ ( y i ) =[ (cid:126)(cid:96)/λ ] σ α σ x τ i = σ (cid:48) α σ x τ i for any i as equality is preserved by consistent sub-stitution. Case
T-Assign : By the inductive hypothesis and application of Item 1.
Case
T-Alias : Θ | λ | Γ [ x : τ ref r ][ y : τ ref r ] (cid:96) alias ( x = y ) ; e : τ ⇒ Γτ ref r + τ ref r ≈ τ (cid:48) ref r (cid:48) + τ (cid:48) ref r (cid:48) Θ | λ | Γ [ x ← (cid:45) τ (cid:48) ref r (cid:48) ][ y ← (cid:45) τ (cid:48) ref r (cid:48) ] (cid:96) e : τ ⇒ Γ From Item 1 we have that [ (cid:126)(cid:96)/λ ] ( τ ref r )+[ (cid:126)(cid:96)/λ ] ( τ ref r ) = [ (cid:126)(cid:96)/λ ] ( τ ref r + τ ref r )and similarly for τ (cid:48) ref r (cid:48) + τ (cid:48) ref r (cid:48) . It therefore remains to show that:[ (cid:126)(cid:96)/λ ] ( τ ref r + τ ref r ) ≈ [ (cid:126)(cid:96)/λ ] ( τ (cid:48) ref r (cid:48) + τ (cid:48) ref r (cid:48) )For which it suffices to show that • (cid:96) [ (cid:126)(cid:96)/λ ] ( τ ref r + τ ref r ) ≤ [ (cid:126)(cid:96)/λ ] ( τ (cid:48) ref r (cid:48) + τ (cid:48) ref r (cid:48) )and • (cid:96) [ (cid:126)(cid:96)/λ ] ( τ (cid:48) ref r (cid:48) + τ (cid:48) ref r (cid:48) ) ≤ [ (cid:126)(cid:96)/λ ] ( τ ref r + τ ref r ). From τ ref r + τ ref r ≈ τ (cid:48) ref r (cid:48) + τ (cid:48) ref r (cid:48) these both follow from Item 3, whereby the result followsfrom the inductive hypothesis. Case
T-AliasPtr : By similar reasoning to the
T-Alias case.
Case
T-Sub : Θ | λ | Γ (cid:96) e : τ ⇒ Γ Γ ≤ Γ Γ , τ ≤ Γ (cid:48) , τ By the induction hypothesis we have that: Θ | (cid:126)(cid:96) | [ (cid:126)(cid:96)/λ ] Γ (cid:96) e : [ (cid:126)(cid:96)/λ ] τ ⇒ [ (cid:126)(cid:96)/λ ] Γ .If we show that [ (cid:126)(cid:96)/λ ] Γ ≤ [ (cid:126)(cid:96)/λ ] Γ and [ (cid:126)(cid:96)/λ ] Γ , [ (cid:126)(cid:96)/λ ] τ ≤ [ (cid:126)(cid:96)/λ ] Γ (cid:48) , [ (cid:126)(cid:96)/λ ] τ we will have the required result. To show the first requirement, for any x ∈ dom ( Γ ) we have that [ (cid:126)(cid:96)/λ ] Γ (cid:96) [ (cid:126)(cid:96)/λ ] Γ ( x ) ≤ [ (cid:126)(cid:96)/λ ] Γ ( x ) from Item 3 so onSORT : Context- and Flow-Sensitive Ownership Refinement Types 41 we have [ (cid:126)(cid:96)/λ ] Γ ≤ [ (cid:126)(cid:96)/λ ] Γ . To show the latter requirement, we observe that[ (cid:126)(cid:96)/λ ] Γ , [ (cid:126)(cid:96)/λ ] τ ≤ [ (cid:126)(cid:96)/λ ] Γ (cid:48) , [ (cid:126)(cid:96)/λ ] τ is equivalent to showing [ (cid:126)(cid:96)/λ ]( Γ , x : τ ) ≤ [ (cid:126)(cid:96)/λ ]( Γ (cid:48) , x : τ ) for some x (cid:54)∈ dom ( Γ ), whereby we have the required subtyp-ing relationship from the application of Item 3. Case
T-Assert : Θ | λ | Γ (cid:96) assert ( ϕ ) ; e : τ ⇒ Γ (cid:48) Γ | = ϕΘ | λ | Γ (cid:96) e : τ ⇒ Γ (cid:48) (cid:15) | Γ (cid:96) WF ϕ By induction hypothesis, the result holds if we can show [ (cid:126)(cid:96)/λ ] Γ | = ϕ whichfollows from Item 4 (that λ (cid:54)∈ FCV ( ϕ ) follows from the well-formedness of ϕ with respect to (cid:15) ). Lemma 10 (Substitution). If Θ | L | Γ (cid:96) e : τ ⇒ Γ (cid:48) and x (cid:48) (cid:54)∈ dom ( Γ ) , then Θ | L | [ x (cid:48) / x ] Γ (cid:96) e : [ x (cid:48) / x ] τ ⇒ [ x (cid:48) / x ] Γ (cid:48) .Proof. By straightforward induction of typing rules.We now prove that if every variable satisfies its refinement in a type environ-ment Γ , we must have | = [ R ] (cid:74) Γ (cid:75) . Lemma 11. If SAT ( H , R , Γ ) then | = [ R ] (cid:74) Γ (cid:75) .Proof. To show | = [ R ] (cid:74) Γ (cid:75) , it suffices to show that for any x ∈ dom ( Γ ) where Γ ( x ) = { ν : int | ϕ } | = [ R ] [ x / ν ] ϕ holds. From SAT ( H , R , Γ ), we must have SATv ( H , R , R ( x ) , Γ ( x )), whereby we have R ( x ) ∈ Z and [ R ] [ R ( x ) /ν ] ϕ . As[ R ] [ x / ν ] ϕ is equivalent to [ R ] [ R ( x ) /ν ] ϕ , and we have the desired result.We prove that subtyping preserves the consistency relation in the followingsense. Lemma 12. If Γ ≤ Γ (cid:48) and Cons ( H , R , Γ ) then:1. For any x ∈ dom ( Γ (cid:48) ) , ∀ a ∈ dom ( H ) . own ( H , R ( x ) , Γ ( x ))( a ) ≤ own ( H , R ( x ) , Γ (cid:48) ( x ))( a ) ∀ a ∈ dom ( H ) . Own ( H , R , Γ (cid:48) )( a ) ≤
3. If Γ (cid:96) τ ≤ τ (cid:48) and SATv ( H , R , v , τ ) then SATv ( H , R , v , τ (cid:48) ) SAT ( H , R , Γ (cid:48) ) Cons ( H , R , Γ (cid:48) ) Proof.
1. By induction on Γ (cid:96) Γ ( x ) ≤ Γ (cid:48) ( x ).2. Direct consequence of 1 and that ∀ a ∈ dom ( H ) . Own ( H , R , Γ )( a ) ≤ Cons ( H , R , Γ ).3. From Cons ( H , R , Γ ) we have SAT ( H , R , Γ ) which by Lemma 11 we have | = [ R ] (cid:74) Γ (cid:75) . We now proceed by induction on Γ (cid:96) τ ≤ τ (cid:48) . Case: τ = { ν : int | ϕ } τ (cid:48) = { ν : int | ϕ (cid:48) }| = (cid:74) Γ (cid:75) ∧ ϕ = ⇒ ϕ (cid:48) From
SATv ( H , R , v , τ ) we have | = [ R ] [ v /ν ] ϕ . We must show that | = [ R ] [ v /ν ] ϕ (cid:48) .From | = (cid:74) Γ (cid:75) ∧ ϕ = ⇒ ϕ (cid:48) we must have | = [ R ] [ v /ν ] (cid:74) Γ (cid:75) ∧ [ R ] [ v /ν ] ϕ = ⇒ [ R ] [ v /ν ] ϕ (cid:48) is valid. As ν does not appear free in (cid:74) Γ (cid:75) , we have | = [ R ] (cid:74) Γ (cid:75) ∧ [ R ] [ v /ν ] ϕ = ⇒ [ R ] [ v /ν ] ϕ (cid:48) is valid whereby the result is immediate. Case: τ = τ p ref r τ (cid:48) = τ (cid:48) p ref r r ≤ r Immediate from the induction hypothesis.4. Immediate consequence of 3 and that Γ ≤ Γ (cid:48) implies that Γ (cid:96) Γ ( x ) ≤ Γ (cid:48) ( x )for any x ∈ dom ( Γ (cid:48) ).5. Immediate from 2 and 4.To show consistency is preserved during evaluation, Lemmas 13 and 14 showtypes equivalent according to ≈ are equivalent for the purposes of own and SATv .Then Lemmas 15 and 16 show that the type addition operator + “distributes”over
SATv and own . Lemma 13 (Type Equivalence Preserves Satisfiability). If τ ≈ τ , then SATv ( H , R , v , τ ) ⇐⇒ SATv ( H , R , v , τ ) .Proof. We prove the forward case by induction on • (cid:96) τ ≤ τ as implied by τ ≈ τ . The inductive case follows from the IH. In the the base case where τ = { ν : int | ϕ } and τ = { ν : int | ϕ } , from • (cid:96) τ ≤ τ we have that | = ϕ = ⇒ ϕ is valid, from which we must have | = [ R ] [ v /ν ] ϕ = ⇒ [ R ] [ v /ν ] ϕ , where fromthe definition of SATv ( H , R , v , τ ) we must then have SATv ( H , R , v , τ ).The backwards case follows similar reasoning by induction on • (cid:96) τ ≤ τ . Lemma 14. If τ ≈ τ , then own ( H , v , τ ) = own ( H , v , τ ) .Proof. By reasoning similar to that in Lemma 13.
Lemma 15. If τ p = τ + τ , then own ( H , v , τ p ) = own ( H , v , τ )+ own ( H , v , τ ) .Proof. By induction on the rules used to derive τ + τ = τ p . Case
Tadd-Int : We have own ( H , v , τ p ) = own ( H , v , τ + τ ), where τ + τ = { ν : int | ϕ ∧ ϕ } , own ( H , v , τ ) and own ( H , v , τ ), where τ = { ν : int | ϕ } , τ = { ν : int | ϕ } .From the definition of ownership, we have own ( H , v , τ p ) = own ( H , v , τ ) = own ( H , v , τ ) = ∅ . It is thus trivial that own ( H , v , τ p ) = own ( H , v , τ ) + own ( H , v , τ ). Case
Tadd-Ref : We assume v = a and a ∈ dom ( H ), otherwise the result trivially holds.We have own ( H , v , τ p ) = own ( H , v , τ + τ ), where τ + τ = ( τ (cid:48) + τ (cid:48) ) ref r + r ,and τ = τ (cid:48) ref r , τ = τ (cid:48) ref r .From the definition of ownership, we have own ( H , v , τ p ) = { a (cid:55)→ r + r } + own ( H , H ( v ) , τ (cid:48) + τ (cid:48) ) and: own ( H , v , τ ) + own ( H , v , τ ) = { a (cid:55)→ r } + own ( H , H ( v ) , τ (cid:48) ) + { a (cid:55)→ r } + own ( H , H ( v ) , τ (cid:48) )= { a (cid:55)→ r + r } + own ( H , H ( v ) , τ (cid:48) ) + own ( H , H ( v ) , τ (cid:48) )By the induction hypothesis, have that own ( H , H ( v ) , τ (cid:48) + τ (cid:48) ) = own ( H , H ( v ) , τ (cid:48) )+ own ( H , H ( v ) , τ (cid:48) ) and can conclude that own ( H , v , τ p ) = own ( H , v , τ ) + own ( H , v , τ ). onSORT : Context- and Flow-Sensitive Ownership Refinement Types 43 Lemma 16. If τ p = τ + τ , we have SATv ( H , R , v, τ p ) iff. SATv ( H , R , v, τ ) and SATv ( H , R , v, τ ) Proof.
By induction on the rules used to derive τ + τ . In the following weonly prove the forward direction of the implication; the backwards direction issymmetric. Case
Tadd-Int : We have
SATv ( H , R , v, τ + τ ), where τ + τ = { ν : int | ϕ ∧ ϕ } , we mustshow SATv ( H , R , v, τ ) and SATv ( H , R , v, τ ), where τ = { ν : int | ϕ } , τ = { ν : int | ϕ } .From the definition of SATv , we must show [ R ] [ v/ν ] ϕ and [ R ] [ v /ν ] ϕ .From SATv ( H , R , v, τ + τ ) we have [ R ] [ v / x ]( ϕ ∧ ϕ ). It is immediate thatfor any value v such that [ R ] [ v /ν ]( ϕ ∧ ϕ ), we must have [ R ] [ v /ν ] ϕ and[ R ] [ v /ν ] ϕ . We then conclude SATv ( H , R , v, τ + τ ) implies SATv ( H , R , v, τ )and SATv ( H , R , v, τ ). Case
Tadd-Ref : Immediate from the definition of
SATv and the inductive hypothesis.
Definition 2.
The valid substitution relation, written R (cid:96) vs τ is the smallestrelation closed under the following rules: ∀ x ∈ FPV ( ϕ ) \ { ν } . ∃ n. R ( x ) = n R (cid:96) vs { ν : int | ϕ } R (cid:96) vs τ R (cid:96) vs τ ref r Lemma 17. If (cid:126)(cid:96) (cid:96) WF Γ and Cons ( H , R , Γ ) , then ∀ x ∈ dom ( Γ ) . R (cid:96) vs Γ ( x ) .Proof. By Cons ( H , R , Γ ), all integer variables in Γ must be in the domain of R and must be an integer. From (cid:126)(cid:96) (cid:96) WF Γ , any free variables in any refinement of anytype in Γ must be an integer valued variable in Γ , which gives the required result. Definition 3.
We will write R (cid:118) R (cid:48) to denote two register files such that:1. dom ( R ) ⊆ dom ( R (cid:48) ) , and2. ∀ x ∈ dom ( R ) . R ( x ) = R (cid:48) ( x ) Definition 4.
Two heaps H and H (cid:48) are equivalent modulo a, written H ≈ a H (cid:48) if:1. dom ( H ) = dom ( H (cid:48) ) ∀ a (cid:48) ∈ dom ( H ) . a (cid:48) (cid:54) = a = ⇒ H ( a ) = H ( a (cid:48) )
3. For any n , H (cid:96) a ⇓ n iff H (cid:48) (cid:96) a ⇓ n Lemma 18.
For any type τ = (cid:62) n , H , v , own ( H , v , (cid:62) n ) = ∅ . Proof.
By induction on τ . In the base case, the result is trivial. Then consider thecase where τ = (cid:62) n − ref . If v (cid:54)∈ Addr , or if v = a and a (cid:54)∈ dom ( H ), then theresult trivially holds. Otherwise the result holds from the inductive hypothesis,the definition of + and { a (cid:55)→ } . Lemma 19 (Heap Update Ownership Preservation).
If H ≈ a H (cid:48) and own ( H , v , τ )( a ) = 0 , then own ( H , v , τ ) = own ( H (cid:48) , v , τ ) .Proof. By induction on the shape of τ . If τ = { ν : int | ϕ } then the result triviallyholds. Otherwise, τ = τ (cid:48) ref r . We assume that v = a (cid:48)(cid:48) and a (cid:48)(cid:48) ∈ dom ( H )(otherwise the result trivially holds, as dom ( H ) = dom ( H (cid:48) ) by H ≈ a H (cid:48) ).Consider the case where a (cid:48)(cid:48) = a . By definition own ( H , a , τ ) = { a (cid:55)→ r } + own ( H , H ( a ) , τ (cid:48) ), and by the assumption that own ( H , a , τ )( a ) = 0 we musthave that r = 0. Further, by the ownership well-formedness of types, we musthave τ (cid:48) = (cid:62) n for some n , thus by Lemma 18 we have own ( H , v , τ ) = ∅ = { a (cid:55)→ } + own ( H (cid:48) , H (cid:48) ( a ) , (cid:62) n ) = own ( H (cid:48) , v , τ ).Finally, consider the case where a (cid:48)(cid:48) (cid:54) = a . Then from the definition of own ( H , a (cid:48)(cid:48) , τ ) and our assumption that own ( H , a (cid:48)(cid:48) , τ )( a ) = 0, we have own ( H , H ( a (cid:48)(cid:48) ) , τ (cid:48) )( a ) =0, and the result holds from the inductive hypothesis and that H ( a (cid:48)(cid:48) ) = H (cid:48) ( a (cid:48)(cid:48) ). Lemma 20.
For any H , R, v , and τ , if SATv ( H , R , v , τ ) then H (cid:96) v ⇓ | τ | Proof.
By induction on τ and the definition of SATv . Lemma 21.
For any n , if H (cid:96) v ⇓ n then for any R, SATv ( H , R , v , (cid:62) n ) .Proof. By induction on n . In the base case, by inversion on H (cid:96) v ⇓ v ∈ Z and as [ R ] [ v /ν ] (cid:62) = ⇒ (cid:62) , we conclude SATv ( H , R , v , (cid:62) ).For n >
0, by inversion on H (cid:96) v ⇓ n we have that v = a , a ∈ dom ( H ), and H (cid:96) H ( a ) ⇓ n −
1, whereby the result holds from the inductive hypothesis.
Lemma 22 (Heap Update Consistency Preservation).
If H ≈ a H (cid:48) and own ( H , v , τ )( a ) = 0 and SATv ( H , R , v , τ ) , then SATv ( H (cid:48) , R , v , τ ) .Proof. By induction on the shape of τ . The base case where τ = { ν : int | ϕ } istrivial. We therefore consider the case where v = a (cid:48) and τ = τ (cid:48) ref r .We first consider the case where a (cid:48) = a , then by our assumption that own ( H , a , τ )( a ) = 0, we must have that τ = τ (cid:48) ref , whereby τ = (cid:62) n for some n . From SATv ( H , R , a , τ ) and Lemma 20, we must have that H (cid:96) a ⇓ | τ | , andfrom H ≈ a H (cid:48) , we therefore have that H (cid:48) (cid:96) a ⇓ | τ | whereby the result holdsfrom Lemma 21.Otherwise, we have that a (cid:48) (cid:54) = a , and by definition we must have that own ( H , H ( a ) , τ (cid:48) )( a ) = 0 and H (cid:48) ( a ) = H ( a ) hence the result follows from theinductive hypothesis. Lemma 23 (Register Weakening). If SATv ( H , R , v, τ ) and R (cid:96) vs τ , thenfor any R (cid:48) such that R (cid:118) R (cid:48) , SATv ( H , R (cid:48) , v, τ ) . onSORT : Context- and Flow-Sensitive Ownership Refinement Types 45 Proof.
By induction on the shape of τ . If τ = τ (cid:48) ref r , then the result follows fromthe inductive hypothesis. We therefore consider the case where τ = { ν : int | ϕ } .Without loss of generality, we consider the case where dom ( R (cid:48) ) \ dom ( R ) = { x } ,and R (cid:48) ( x ) = n . (If R (cid:48) ( x ) = a , the extra binding also has no effect, and thecase where more than one binding is added follows from n applications of thefollowing argument.)From SATv ( H , R , v, τ ), we conclude that v ∈ Z and that [ R ] [ v/ν ] ϕ . If x (cid:54)∈ FPV ( ϕ ) then [ R ] [ v/ν ] ϕ ⇐⇒ [ R (cid:48) ] [ v/ν ] ϕ and the result holds trivially.Otherwise, if x ∈ FPV ( ϕ ) and x (cid:54)∈ dom ( R ) then R is not a valid substitution,violating our assumption. Lemma 24 (Heap Extension Consistency Preservation).
If we have heap H , such that SATv ( H , R , v , τ ) , for any heap H (cid:48) = H { a (cid:55)→ v (cid:48) } , a (cid:54)∈ dom ( H ) ,then we have SATv ( H (cid:48) , R , v , τ ) .Proof. By induction on the shape of τ . The base case where τ = { ν : int | ϕ } is trivial. Next, we consider the case where τ = τ (cid:48) ref r . We must show that v ∈ dom ( H (cid:48) ) and SATv ( H (cid:48) , R , H (cid:48) ( v ) , τ (cid:48) ). The first condition is immediatelysatisfied by inversion on SATv ( H , R , v , τ (cid:48) ), and from a (cid:54)∈ dom ( H ), we have v (cid:54) = a ,which gives that H (cid:48) ( v ) = H ( v ). That is we must show SATv ( H (cid:48) , R , H ( v ) , τ (cid:48) ),which is follows from the induction hypothesis. Lemma 25 (Heap Extension Ownership Preservation). If SATv ( H , R , v , τ ) ,then for any a (cid:54)∈ dom ( H ) own ( H , v , τ ) = own ( H { a (cid:55)→ v (cid:48) } , v , τ ) for any valuev (cid:48) .Proof. By induction on τ . The base case is trivial as own ( H , v , { ν : int | ϕ } ) = ∅ = own ( H { a (cid:55)→ v } , v , { ν : int | ϕ } ). We therefore consider the case where τ = τ (cid:48) ref r .From SATv ( H , R , v , τ ) we must have that v = a (cid:48) and a (cid:48) ∈ dom ( H ) (andby extension a (cid:48) ∈ dom ( H { a (cid:55)→ v (cid:48) } )). From the definition of the ownershipfunction, we have that own ( H , v , τ ) = own ( H , H ( a ) , τ (cid:48) ) + { a (cid:48) (cid:55)→ r } . and own ( H { a (cid:55)→ v (cid:48) } , v , τ ) = own ( H { a (cid:55)→ v (cid:48) } , H { a (cid:55)→ v (cid:48) } ( a (cid:48) ) , τ (cid:48) ) + { a (cid:48) (cid:55)→ r } Then from our requirement that a (cid:54)∈ dom ( H ), we have a (cid:54) = a (cid:48) and therefore H ( a (cid:48) ) = H { a (cid:55)→ v (cid:48) } ( a (cid:48) ), whereby the result holds from the inductive hypothesis. Lemma 26 (Environment Weakening).
Define the partial operation Γ (cid:93) Γ for two environments such dom ( Γ ) ∩ dom ( Γ ) = ∅ : ( Γ (cid:93) Γ ) ( x ) = Γ ( x ) x ∈ dom ( Γ ) Γ ( x ) x ∈ dom ( Γ ) undef o.w. Then, for any Γ and Γ (cid:48)(cid:48) where dom ( Γ ) ∩ dom ( Γ (cid:48)(cid:48) ) = ∅ :1. Γ (cid:96) τ ≤ τ implies Γ (cid:93) Γ (cid:48)(cid:48) (cid:96) τ ≤ τ Γ ≤ Γ (cid:48) implies Γ (cid:93) Γ (cid:48)(cid:48) ≤ Γ (cid:48) (cid:93) Γ (cid:48)(cid:48)
3. If Θ | L | Γ (cid:96) e : τ ⇒ Γ (cid:48) , L (cid:96) WF Γ (cid:93) Γ (cid:48)(cid:48) , and L (cid:96) WF Γ (cid:48) (cid:93) Γ (cid:48)(cid:48) , then Θ | L | Γ (cid:93) Γ (cid:48)(cid:48) (cid:96) e : τ ⇒ Γ (cid:48)(cid:48) (cid:93) Γ Proof.
1. As in the proof of Lemma 9 (part 3), at the root of the subtyping derivationis a logical judgment of the form | = (cid:74) Γ (cid:75) ∧ ϕ = ⇒ ϕ which can be shownto be valid. We must then show that | = (cid:74) Γ (cid:93) Γ (cid:48)(cid:48) (cid:75) ∧ ϕ = ⇒ ϕ is valid. As (cid:74) Γ (cid:48)(cid:48) (cid:93) Γ (cid:75) ∧ ϕ = (cid:74) Γ (cid:48)(cid:48) (cid:75) ∧ (cid:74) Γ (cid:75) ∧ ϕ only strengthens the pre-condition (cid:74) Γ (cid:75) ∧ ϕ , | = (cid:74) Γ (cid:48)(cid:48) (cid:93) Γ (cid:75) ∧ ϕ = ⇒ ϕ must also be valid.2. It suffices to show that Γ (cid:93) Γ (cid:48)(cid:48) (cid:96) ( Γ (cid:93) Γ (cid:48)(cid:48) )( x ) ≤ ( Γ (cid:48) (cid:93) Γ (cid:48)(cid:48) )( x ) for any arbitrary x ∈ dom ( Γ (cid:48) (cid:93) Γ (cid:48)(cid:48) ). If x ∈ dom ( Γ (cid:48) ) then we must have Γ (cid:96) Γ ( x ) ≤ Γ (cid:48) ( x ) byinversion on Γ ≤ Γ (cid:48) , whereby Γ (cid:93) Γ (cid:48)(cid:48) (cid:96) ( Γ (cid:93) Γ (cid:48)(cid:48) )( x ) = Γ ( x ) ≤ Γ (cid:48) (cid:93) Γ (cid:48)(cid:48) ( x ) = Γ (cid:48) ( x ) from part 1.If x (cid:54)∈ dom ( Γ (cid:48) ), then we must show ( Γ (cid:93) Γ (cid:48)(cid:48) ) (cid:96) Γ (cid:48)(cid:48) ( x ) ≤ Γ (cid:48)(cid:48) ( x ), whichtrivially holds.3. By induction on the typing derivation of Θ | L | Γ (cid:96) e : τ ⇒ Γ (cid:48) . We assumethat the variables bound in any let expressions that appear within e are notin the domain of Γ (cid:48)(cid:48) ; this requirement can be easily enforced with consistentrenaming and is preserved during evaluation. The only interesting cases are T-Sub and
T-Assert and the let bindings; the other cases follow from theinduction hypothesis.We now prove the relevant cases.
Case
T-Let : Θ | L | Γ (cid:96) let x = y in e : τ ⇒ Γ (cid:48) Θ | L | Γ [ y ← (cid:45) τ ∧ y y = τ x ] , x : τ ∧ x x = τ y (cid:96) e : τ ⇒ Γ (cid:48) Γ ( y ) = τ + τ x (cid:54)∈ dom ( Γ (cid:48) )Let Γ (cid:48)(cid:48)(cid:48) = Γ (cid:48)(cid:48) (cid:93) Γ [ y ← (cid:45) τ ∧ y y = τ x ] , x : τ ∧ x x = τ y . To use the in-ductive hypothesis, we must show that L (cid:96) WF Γ (cid:48)(cid:48)(cid:48) and L (cid:96) WF Γ (cid:48) (cid:93) Γ (cid:48)(cid:48) .The latter holds by assumption. To show the former, it suffices to show L | Γ (cid:48)(cid:48)(cid:48) (cid:96) WF τ ∧ y y = τ x and L | Γ (cid:48)(cid:48)(cid:48) (cid:96) WF τ ∧ x x = τ y . From the as-sumed well-formedness L (cid:96) WF Γ (cid:93) Γ (cid:48)(cid:48) , we must have L | Γ (cid:93) Γ (cid:48)(cid:48) (cid:96) WF τ + τ ,and in particular L | Γ (cid:93) Γ (cid:48)(cid:48) (cid:96) WF τ and L | Γ (cid:93) Γ (cid:48)(cid:48) (cid:96) WF τ . From thiswe conclude both conditions hold. To show the well-typing of the overall letexpression, we must show x (cid:54)∈ dom ( Γ (cid:48) (cid:93) Γ (cid:48)(cid:48) ), which follows from our assump-tion and x (cid:54)∈ dom ( Γ (cid:48) ). Finally, we must also show that L | Γ (cid:48) (cid:93) Γ (cid:48)(cid:48) (cid:96) WF τ .From L | Γ (cid:48) (cid:96) WF τ and the fact that ∀ x ∈ dom ( Γ (cid:48) ) .Γ (cid:48) ( x ) = { ν : int | } iff( Γ (cid:48) (cid:93) Γ (cid:48)(cid:48) )( x ) = { ν : int | } , we must have L | Γ (cid:48) (cid:93) Γ (cid:48)(cid:48) (cid:96) WF τ . Cases
T-LetInt , T-Mkref , T-Mkref , T-Deref , T-Call : Similar to the reasoning in
T-Let . Case
T-Sub : Γ ≤ Γ Θ | L | Γ (cid:96) e : τ ⇒ Γ Γ , τ ≤ Γ (cid:48) , τ From the rules for subtyping, we must have dom ( Γ ) ⊆ dom ( Γ ) and dom ( Γ (cid:48) ) ⊆ dom ( Γ ). A simple inductive argument gives that dom ( Γ ) ⊆ dom ( Γ ), there-fore we have dom ( Γ (cid:48) ) ⊆ dom ( Γ ). Let LV be the set of free variables in the onSORT : Context- and Flow-Sensitive Ownership Refinement Types 47 refinements of Γ (cid:48)(cid:48) that are not in the domain of Γ (cid:48)(cid:48) . From the assumed well-formedness of L (cid:96) WF Γ (cid:48) (cid:93) Γ (cid:48)(cid:48) , we must have that ∀ x ∈ LV . x ∈ dom ( Γ (cid:48) ) ∧ Γ (cid:48) ( x ) = { ν : int | } . Thus, LV ⊆ Γ and LV ⊆ Γ . Further, by definition, forany Γ p ≤ Γ q , if Γ q ( x ) = { ν : int | } then Γ p ( x ) = { ν : int | } , i.e. subtypingpreserves simple types. We conclude that L (cid:96) WF Γ (cid:93) Γ (cid:48)(cid:48) and L (cid:96) WF Γ (cid:93) Γ (cid:48)(cid:48) ,whereby the inductive hypothesis gives Θ | L | Γ (cid:93) Γ (cid:48)(cid:48) (cid:96) e : τ ⇒ Γ (cid:93) Γ (cid:48)(cid:48) .To prove the overall result, we must show that Γ (cid:93) Γ (cid:48)(cid:48) ≤ Γ (cid:93) Γ (cid:48)(cid:48) and Γ (cid:93) Γ (cid:48)(cid:48) , τ ≤ Γ (cid:48) (cid:93) Γ (cid:48)(cid:48) , τ which follow from parts 1 and 2 above. That L | Γ (cid:93) Γ (cid:48)(cid:48) (cid:96) WF τ follows by reasoning to the case for T-Let above.
Case
T-Assert : We must show that | = (cid:74) Γ (cid:48)(cid:48) (cid:93) Γ (cid:75) = ⇒ ϕ which is equivalent to | = (cid:74) Γ (cid:48)(cid:48) (cid:75) ∧ (cid:74) Γ (cid:75) = ⇒ ϕ . As the source term was well typed, | = (cid:74) Γ (cid:75) = ⇒ ϕ is valid, wemust then have | = (cid:74) Γ (cid:48)(cid:48) (cid:75) ∧ (cid:74) Γ (cid:75) = ⇒ ϕ whereby the inductive hypothesis givesthe required result. C Proof of Lemma 3
We first prove two additional lemmas. Lemmas 27 and 28 give key facts usedin the return and call cases respectively; we have separated them into separatelemmas for clarity.
Lemma 27.
For any Γ such that Θ | (cid:96) : (cid:126)(cid:96) | Γ (cid:96) x : τ ⇒ Γ and Θ | [] : τ ⇒ Γ | (cid:126)(cid:96) (cid:96) ectx E [ let y = [] (cid:96) in e ] : τ ⇒ Γ then Θ | (cid:126)(cid:96) | Γ (cid:96) E [ let y =[] (cid:96) in e ][ x ] : τ ⇒ Γ .Proof. It suffices to show that Θ | (cid:126)(cid:96) | Γ (cid:96) let y = x in e : τ (cid:48) ⇒ Γ (cid:48) and Θ | [] : τ (cid:48) ⇒ Γ (cid:48) | (cid:126)(cid:96) (cid:96) ectx E : τ ⇒ Γ for some τ (cid:48) and Γ (cid:48) whereby the result will holdfrom Lemma 8.By inversion on Θ | [] : τ ⇒ Γ | (cid:126)(cid:96) (cid:96) ectx E [ let y = [] (cid:96) in e ] : τ ⇒ Γ we have Θ | (cid:126)(cid:96) | Γ , y : τ (cid:96) e : τ (cid:48)(cid:48) ⇒ Γ (cid:48)(cid:48) (1) Θ | [] : τ (cid:48)(cid:48) ⇒ Γ (cid:48)(cid:48) | L (cid:96) ectx E : τ ⇒ Γ (2) y (cid:54)∈ dom ( Γ (cid:48)(cid:48) ) (3)We take Γ (cid:48) = Γ (cid:48)(cid:48) , τ (cid:48) = τ (cid:48)(cid:48) , and then Equation (2) gives the necessary typing for E .It remains to to show that Θ | (cid:126)(cid:96) | Γ (cid:96) let y = x in e : τ (cid:48) ⇒ Γ (cid:48) (That (cid:126)(cid:96) (cid:96) WF τ (cid:48) ⇒ Γ (cid:48) follows from Equation (1)) By Lemma 6, from Θ | (cid:96) : (cid:126)(cid:96) | Γ (cid:96) x : τ ⇒ Γ we conclude there exists some Γ p , τ p , and Γ (cid:48) p such: Γ ≤ Γ p (4) Γ (cid:48) p , τ p ≤ Γ , τ (5) Γ (cid:48) p = Γ p [ x ← (cid:45) τ (cid:48) p ] (6) Γ p ( x ) = τ p + τ (cid:48) p (7) (cid:126)(cid:96) (cid:96) WF Γ p (8)We first apply T-Sub with Equations (4) and (8), so it remains to show Θ | (cid:126)(cid:96) | Γ p [ x : τ p + τ (cid:48) p ] (cid:96) let y = x in e : τ (cid:48) ⇒ Γ (cid:48) which, by T-Let holds if we show that: Θ | (cid:126)(cid:96) | Γ p [ x ← (cid:45) τ (cid:48) p ∧ x x = τ (cid:48) p y ] , y : τ p ∧ y y = τ p x (cid:96) e : τ (cid:48) ⇒ Γ (cid:48) ( y (cid:54)∈ dom ( Γ (cid:48) ) follows from Equation (3), and the well-formedness of Γ p [ x ← (cid:45)τ (cid:48) p ∧ x x = τ (cid:48) p y ] , y : τ p ∧ y y = τ p x follows from the well-formedness of Γ p , τ p and τ (cid:48) p and that x and y appear in the refinements iff they are mapped to integertypes in the new type environment.)We can use T-Sub to weaken the type environment to: Θ | (cid:126)(cid:96) | Γ p [ x ← (cid:45) τ (cid:48) p ] , y : τ p (cid:96) e : τ (cid:48) ⇒ Γ (cid:48) From Equation (5) above, we have that Γ p [ x ← (cid:45) τ (cid:48) p ] , y : τ p ≤ Γ , y : τ , wherebyone final application of T-Sub allows us to use to Equation (1) above.
Lemma 28.
Let E [ let x = f (cid:96) ( y , . . . , y n ) in e (cid:48) ] be a term such that: Θ | (cid:126)(cid:96) | Γ (cid:96) let x = f (cid:96) ( y , . . . , y n ) in e (cid:48) : τ ⇒ Γ σ α = [ (cid:96) : (cid:126)(cid:96)/λ ] Θ | [] : τ ⇒ Γ | (cid:126)(cid:96) (cid:96) ectx E : τ ⇒ Γ σ x = [ y / x ] · · · [ y n / x n ] f (cid:55)→ ( x , .. , x n ) e ∈ D Θ (cid:96) f (cid:55)→ ( x , .. , x n ) e (cid:96) WF Θ where Θ ( f ) = ∀ λ. (cid:104) x : τ , . . . , x n : τ n (cid:105) → (cid:104) x : τ (cid:48) , . . . , x n : τ (cid:48) n | τ q (cid:105) .Then there exist some τ and Γ : Θ | (cid:96) : (cid:126)(cid:96) | Γ (cid:96) σ x e : τ ⇒ Γ Θ | [] : τ ⇒ Γ | (cid:126)(cid:96) (cid:96) ectx E [ let x = [] (cid:96) in e ] : τ ⇒ Γ Proof.
From Lemma 6 on Θ | (cid:126)(cid:96) | Γ (cid:96) let x = f (cid:96) ( y , . . . , y n ) in e (cid:48) : τ ⇒ Γ wehave, for some Γ p , τ p , Γ (cid:48) p , that: Γ ≤ Γ p (9) Γ (cid:48) p , τ p ≤ Γ , τ (10) Γ p ( y i ) = σ α σ x τ i (11) (cid:126)(cid:96) (cid:96) WF Γ p (12) Θ | (cid:126)(cid:96) | Γ p [ y i ← (cid:45) σ α σ x τ (cid:48) i ] , x : σ α σ x τ q (cid:96) e (cid:48) : τ p ⇒ Γ (cid:48) p (13) x (cid:54)∈ dom ( Γ (cid:48) p ) (14) onSORT : Context- and Flow-Sensitive Ownership Refinement Types 49 To prove the first part, from the well-typing of the function body, wehave Θ | λ | x : τ , . . . , x n : τ n (cid:96) e : τ q ⇒ x : τ (cid:48) , . . . , x n : τ (cid:48) n . From our assump-tion that all variable names are distinct, by n applications of the substitu-tion lemma (Lemma 10) we have: Θ | λ | y : σ x τ , . . . , y n : σ x τ n (cid:96) σ x e : σ x τ q ⇒ y : σ x τ (cid:48) , . . . , y n : σ x τ (cid:48) n . By Lemma 9 (part 5) we then have Θ | (cid:96) : (cid:126)(cid:96) | y : σ α σ x τ , . . . , y n : σ α σ x τ n (cid:96) σ x e : σ α σ x τ q ⇒ y : σ α σ x τ (cid:48) , . . . , y n : σ α σ x τ (cid:48) n .We take τ = σ α σ x τ q and Γ = Γ p [ y i ← (cid:45) σ α σ x τ (cid:48) i ].By the well-formedness of function types and well-formedness of Γ p , we musthave that (cid:96) : (cid:126)(cid:96) (cid:96) WF Γ . Then by Equations (11) and (12) and lemma 26 we have Θ | (cid:96) : (cid:126)(cid:96) | Γ p (cid:96) σ x e : τ ⇒ Γ , whereby Equation (9) and an application of T-Sub gives Θ | (cid:96) : (cid:126)(cid:96) | Γ (cid:96) σ x e : τ ⇒ Γ , i.e., the first result.To prove the second part, from the typing rule for TE-Stack we must show: Θ | [] : τ ⇒ Γ | (cid:126)(cid:96) (cid:96) ectx E : τ ⇒ Γ (15) x (cid:54)∈ dom ( Γ ) (16) Θ | (cid:126)(cid:96) | Γ , x : τ (cid:96) e (cid:48) : τ ⇒ Γ (17)Equation (15) holds by assumption, and Equation (16) follows from Equation (14)and that Γ (cid:48) p ≤ Γ implies dom ( Γ ) ⊆ dom ( Γ (cid:48) p ). (cid:126)(cid:96) (cid:96) WF τ ⇒ Γ follows fromthe well-typing of the function call term, and (cid:126)(cid:96) (cid:96) WF Γ , x : τ follows fromEquation (13).From Equations (10) and (13) we then have Equation (17) via an applicationof T-Sub . Proof (Preservation; Lemma 3).
The proof is organized by cases analysis onthe transition rule used of e , and showing that the output configuration is welltyped by (cid:96) D conf . We must therefore find a Γ (cid:48)(cid:48) that is consistent with H (cid:48) and R (cid:48) and also satisfies the other conditions imposed by the definition of (cid:96) D conf . Here Γ (cid:48)(cid:48) , H (cid:48) , R (cid:48) represent the type environment, heap and register after the transitionrespectively. We identify the heap and register file before transition with H and R respectively. In order to show that the ownership invariant is preserved, we needto prove that ∀ a ∈ dom ( H ) . Own ( H , R , Γ (cid:48)(cid:48) )( a ) ≤
1. In many cases, we will showthat
Own ( H , R , Γ ) = Own ( H (cid:48) , R (cid:48) , Γ (cid:48)(cid:48) ), whereby from the assumption that Cons ( H , R , Γ ) as implied by (cid:96) D conf we have ∀ a ∈ dom ( H ) . Own ( H , R , Γ )( a ) ≤
1, giving the desired result.
Case
R-Var : (cid:96) D conf (cid:68) H , R , F n − : (cid:126)F , x (cid:69) , (cid:68) H , R , F n − : (cid:126)F , x (cid:69) −→ D (cid:68) H , R , (cid:126)F , F n − [ x ] (cid:69) By inversion on configuration typing (cid:96) D conf (cid:68) H , R , F n − : (cid:126)F , x (cid:69) , we have: Θ | (cid:126)(cid:96) | Γ (cid:96) x : τ n ⇒ Γ n ∀ i ∈ { ..n } .Θ | [] : τ i ⇒ Γ i | (cid:126)(cid:96) i − (cid:96) ectx F i − : τ i − ⇒ Γ i − Using Lemma 27, we can conclude that Θ | (cid:126)(cid:96) n − | Γ (cid:96) F n − [ x ] : τ n − ⇒ Γ n − .We therefore take Γ (cid:48)(cid:48) = Γ . It remains to show that
Cons ( H , R , Γ (cid:48)(cid:48) ) which follows immediately from Cons ( H , R , Γ ). Case
R-Deref : (cid:96) D conf (cid:68) H , R , (cid:126)F , E [ let x = ∗ y in e ] (cid:69)(cid:68) H , R , (cid:126)F , E [ let x = ∗ y in e ] (cid:69) −→ D (cid:68) H , R { x (cid:48) (cid:55)→ v } , (cid:126)F , E [[ x (cid:48) / x ] e ] (cid:69) H ( a ) = v R ( y ) = a R (cid:48) = R { x (cid:48) (cid:55)→ v } By inversion on the configuration typing relationship, we have that: Θ | (cid:126)(cid:96) | Γ (cid:96) E [ let x = ∗ y in e ] : τ n ⇒ Γ n Cons ( H , R , Γ )By Lemma 7, we have some τ, Γ (cid:48) such that: Θ | [] : τ ⇒ Γ (cid:48) | (cid:126)(cid:96) (cid:96) ectx E : τ n ⇒ Γ n Θ | (cid:126)(cid:96) | Γ (cid:96) let x = ∗ y in e : τ ⇒ Γ (cid:48) Using Lemma 6, we have some Γ p , Γ (cid:48) p and τ p such that: Γ ≤ Γ p (cid:126)(cid:96) (cid:96) WF Γ p Γ (cid:48) p , τ p ≤ Γ (cid:48) , τΓ p ( y ) = ( τ + τ ) ref r x (cid:54)∈ dom ( Γ (cid:48) p ) τ (cid:48)(cid:48) = (cid:40) ( τ ∧ y y = τ x ) r > τ r = 0 Θ | (cid:126)(cid:96) | Γ p [ y ← (cid:45) τ (cid:48)(cid:48) ref r ] , x : τ (cid:96) e : τ p ⇒ Γ (cid:48) p From Lemma 12, we then have
Cons ( H , R , Γ p ). We will now show that: Cons ( H , R { x (cid:48) (cid:55)→ v } , Γ (cid:48)(cid:48) ) (18) Θ | (cid:126)(cid:96) | Γ (cid:48)(cid:48) (cid:96) [ x (cid:48) / x ] e : [ x (cid:48) / x ] τ p ⇒ [ x (cid:48) / x ] Γ (cid:48) p (19)where Γ (cid:48)(cid:48) = Γ p [ y ← (cid:45) ([ x (cid:48) / x ] τ (cid:48)(cid:48) ) ref r ] , x (cid:48) : τ .Together these give our desired result. To see how, from Θ | (cid:126)(cid:96) | Γ p [ y ← (cid:45)τ (cid:48)(cid:48) ref r ] , x : τ (cid:96) e : τ p ⇒ Γ (cid:48) p above, we must have that (cid:126)(cid:96) (cid:96) WF τ p ⇒ Γ (cid:48) p . From x (cid:54)∈ dom ( Γ (cid:48) p ) we must therefore have that [ x (cid:48) / x ] τ p = τ p and [ x (cid:48) / x ] Γ (cid:48) p = Γ (cid:48) p . As Γ (cid:48) p , τ p ≤ Γ (cid:48) , τ an application of T-Sub gives Θ | (cid:126)(cid:96) | Γ (cid:48)(cid:48) (cid:96) [ x (cid:48) / x ] e : τ ⇒ Γ (cid:48) . ThenLemma 8 will give that Θ | (cid:126)(cid:96) | Γ (cid:48)(cid:48) (cid:96) E [[ x (cid:48) / x ] e ] : τ n ⇒ Γ n .As E and the stack (cid:126)F remained unchanged, combined with Equation (18) thisgives (cid:96) D conf (cid:68) H , R { x (cid:48) (cid:55)→ v } , (cid:126)F , E [[ x (cid:48) / x ] e ] (cid:69) as required. As the above argumentis used almost completely unchanged in all of the following cases, we will invertthe redex without regard for the T-Sub rule, with the understanding that thesubtyping rule is handled with an argument identical to the above.We now show that Θ | (cid:126)(cid:96) | Γ (cid:48)(cid:48) (cid:96) [ x (cid:48) / x ] e : [ x / x (cid:48) ] τ p ⇒ [ x (cid:48) / x ] Γ (cid:48) and Cons ( H , R { x (cid:48) (cid:55)→ v } , Γ (cid:48)(cid:48) ). The first is easy to obtain using Lemma 10; from Cons ( H , R , Γ ), wehave that ∀ x ∈ dom ( Γ ) . x ∈ dom ( R ), whereby from x (cid:54)∈ dom ( R ) we have x (cid:48) (cid:54)∈ dom ( Γ ). It therefore remains to show Cons ( H , R { x (cid:48) (cid:55)→ v } , Γ (cid:48)(cid:48) ). onSORT : Context- and Flow-Sensitive Ownership Refinement Types 51 To show
SAT ( H , R , Γ (cid:48)(cid:48) ), it suffices to show that SATv ( H , R (cid:48) , R (cid:48) ( x (cid:48) ) , τ ) and SATv ( H , R (cid:48) , H ( R (cid:48) ( y )) , τ (cid:48)(cid:48) ) (that SATv holds for all other variables z followsfrom Γ ( z ) = Γ (cid:48)(cid:48) ( z ) and Lemmas 17 and 23). If τ is an integer type and r > SATv ( H , R (cid:48) , H ( R (cid:48) ( y )) , τ ) and that R (cid:48) ( x (cid:48) ) = H ( R (cid:48) ( y )) = H ( R ( y )),which is immediate from the definition of R-Deref . If τ is not an integer or if r = 0, then we must only show that SATv ( H , R (cid:48) , H ( R (cid:48) ( y )) , τ ).From Cons ( H , R , Γ p ), we know that SAT ( H , R , Γ p ), in particular, SATv ( H , R , R ( y ) , Γ p ( y )).Then by Lemmas 16, 17 and 23, from R (cid:118) R (cid:48) , (cid:126)(cid:96) (cid:96) WF Γ p , and SATv ( H , R , v , τ + τ ) we obtain that SATv ( H , R (cid:48) , v , τ ) and SATv ( H , R (cid:48) , v , τ ), where v = H ( R ( y )). We thus have that SATv ( H , R (cid:48) , R (cid:48) ( x (cid:48) ) , τ ) and SATv ( H , R (cid:48) , H ( R (cid:48) ( y )) , τ )are satisfied.We must also show that the ownership invariant is preserved. Then, it’s toshow ∀ a ∈ dom ( H ) . Own ( H , R (cid:48) , Γ (cid:48)(cid:48) )( a ) ≤
1. Define O (cid:48) and O (cid:48) as follows: Own ( H , R , Γ p ) = O (cid:48) + own ( H , R ( y ) , Γ p ( y )) Own ( H , R (cid:48) , Γ (cid:48)(cid:48) ) = O (cid:48) + own ( H , R (cid:48) ( y ) , Γ (cid:48)(cid:48) ( y )) + own ( H , R (cid:48) ( x (cid:48) ) , Γ (cid:48)(cid:48) ( x (cid:48) )) O (cid:48) = Σ z ∈ dom ( Γ ) \{ y } own ( H , R ( z ) , Γ p ( z )) O (cid:48) = Σ z ∈ dom ( Γ (cid:48)(cid:48) ) \{ y , x (cid:48) } own ( H , R (cid:48) ( z (cid:48) ) , Γ (cid:48)(cid:48) ( z (cid:48) ))By Lemma 19, O (cid:48) = O (cid:48) holds. Then, it suffices to show that own ( H , R ( y ) , Γ p ( y )) = own ( H , R (cid:48) ( y ) , Γ (cid:48)(cid:48) ( y )) + own ( H , R (cid:48) ( x (cid:48) ) , Γ (cid:48)(cid:48) ( x (cid:48) )).As R (cid:48) ( x (cid:48) ) = H ( R (cid:48) ( y )) = H ( R ( y )) and from the definition of Γ (cid:48)(cid:48) , we have: own ( H , R (cid:48) ( x (cid:48) ) , Γ (cid:48)(cid:48) ( x (cid:48) )) = own ( H , H ( R ( y )) , τ ) own ( H , R (cid:48) ( y ) , Γ (cid:48)(cid:48) ( y )) = { a (cid:55)→ r } + own ( H , H ( R ( y )) , τ )From the definition of the ownership function, we have that own ( H , R ( y ) , Γ p ( y )) = { a (cid:55)→ r } + own ( H , H ( R ( y )) , τ + τ )which, by Lemma 15, is equivalent to: { a (cid:55)→ r } + own ( H , H ( R ( y )) , τ ) + own ( H , H ( R ( y )) , τ )We therefore have own ( H , R ( y ) , Γ ( y )) = own ( H , R (cid:48) ( y ) , Γ (cid:48)(cid:48) ( y ))+ own ( H , R (cid:48) ( x (cid:48) ) , Γ (cid:48)(cid:48) ( x (cid:48) )),and conclude that Own ( H , R , Γ ) = Own ( H , R (cid:48) , Γ (cid:48)(cid:48) ). Case
R-Seq : (cid:96) D conf (cid:68) H , R , (cid:126)F , E [ x ; e ] (cid:69)(cid:68) H , R , (cid:126)F , E [ x ; e ] (cid:69) −→ D (cid:68) H , R , (cid:126)F , E [ e ] (cid:69) By inversion (see
R-Deref ) we have for some Γ that: Θ | (cid:126)(cid:96) | Γ [ x : τ + τ ] (cid:96) x : τ ⇒ Γ [ x ← (cid:45) τ ] Θ | (cid:126)(cid:96) | Γ [ x ← (cid:45) τ ] (cid:96) e : τ (cid:48) ⇒ Γ (cid:48) Cons ( H , R , Γ ) We take Γ (cid:48)(cid:48) = Γ [ x ← (cid:45) τ ].It suffices to show (see R-Deref ) that Θ | (cid:126)(cid:96) | Γ (cid:48)(cid:48) (cid:96) e : τ (cid:48) ⇒ Γ (cid:48) , and Cons ( H , R , Γ (cid:48)(cid:48) ). The first is immediate from the inversion above, and Cons ( H , R , Γ (cid:48)(cid:48) )follows from Lemmas 15 and 16. Case
R-Let : (cid:96) D conf (cid:68) H , R , (cid:126)F , E [ let x = y in e ] (cid:69)(cid:68) H , R , (cid:126)F , E [ let x = y in e ] (cid:69) −→ D (cid:68) H , R { x (cid:48) (cid:55)→ R ( y ) } , (cid:126)F , E [[ x (cid:48) / x ] e ] (cid:69) x (cid:48) (cid:54)∈ dom ( R ) R (cid:48) = R { x (cid:48) (cid:55)→ R ( y ) } By inversion (see
R-Deref ) we have that for some Γ that: (cid:126)(cid:96) (cid:96) WF ΓΓ ( y ) = τ + τ Θ | (cid:126)(cid:96) | Γ [ y ← (cid:45) τ ∧ y y = τ x ] , x : ( τ ∧ x x = τ y ) (cid:96) e : τ ⇒ Γ (cid:48) Cons ( H , R , Γ ) x (cid:54)∈ dom ( Γ (cid:48) )We give Γ (cid:48)(cid:48) = Γ [ y ← (cid:45) τ ∧ y y = τ x (cid:48) ] , x (cid:48) : ( τ ∧ x (cid:48) x (cid:48) = τ y ).It suffices to show (see R-Deref ) that Θ | (cid:126)(cid:96) | Γ (cid:48)(cid:48) (cid:96) [ x (cid:48) / x ] e : τ ⇒ Γ (cid:48) and Cons ( H , R { x (cid:48) (cid:55)→ R ( y ) } , Γ (cid:48)(cid:48) ). The first is easy to obtain using reasoning as inthe R-Deref case. It therefore remains to show
Cons ( H , R (cid:48) , Γ (cid:48)(cid:48) ).To show that the output environment is consistent, we must show that SATv ( H , R (cid:48) , R (cid:48) ( x (cid:48) ) , τ ∧ x (cid:48) x (cid:48) = y ) and SATv ( H , R (cid:48) , R (cid:48) ( y ) , τ ∧ y y = x (cid:48) ). Byreasoning similar to that in R-Deref , it suffices to show that
SATv ( H , R (cid:48) , R (cid:48) ( x (cid:48) ) , τ )and SATv ( H , R (cid:48) , R (cid:48) ( y ) , τ ). We know that Cons ( H , R , Γ ), from which me have SAT ( H , R , Γ ), in particular y ∈ dom ( R ) and SATv ( H , R , R ( y ) , Γ ( y )). As R (cid:118) R (cid:48) and (cid:126)(cid:96) (cid:96) WF Γ , from Lemmas 16, 17 and 23, we obtain from SATv ( H , R , v , τ + τ ) that SATv ( H , R (cid:48) , v , τ ) and SATv ( H , R (cid:48) , v , τ ) where v = R ( y ). We thenhave SATv ( H , R (cid:48) , R (cid:48) ( x (cid:48) ) , τ ) and SATv ( H , R (cid:48) , R (cid:48) ( y ) , τ ) are satisfied.We must also show that the ownership invariant is preserved. Then, it’s toshow ∀ a ∈ dom ( H ) . Own ( H , R (cid:48) , Γ (cid:48)(cid:48) )( a ) ≤
1. Define O (cid:48) and O (cid:48) as follows: Own ( H , R , Γ ) = O (cid:48) + own ( H , R ( y ) , Γ ( y )) Own ( H , R (cid:48) , Γ (cid:48)(cid:48) ) = O (cid:48) + own ( H , R (cid:48) ( y ) , Γ (cid:48)(cid:48) ( y )) + own ( H , R (cid:48) ( x (cid:48) ) , Γ (cid:48)(cid:48) ( x (cid:48) )) O (cid:48) = Σ z ∈ dom ( Γ ) \{ y } own ( H , R ( z ) , Γ ( z )) O (cid:48) = Σ z ∈ dom ( Γ (cid:48)(cid:48) ) \{ y , x (cid:48) } own ( H , R (cid:48) ( z (cid:48) ) , Γ (cid:48)(cid:48) ( z (cid:48) ))By Lemma 19, O (cid:48) = O (cid:48) holds. That own ( H , R (cid:48) ( x (cid:48) ) , τ ) + own ( H , R (cid:48) ( y ) , τ ) = own ( H , R ( y ) , τ + τ ) follows immediately from Lemma 15 and the condi-tion R ( y ) = R (cid:48) ( x (cid:48) ) = R (cid:48) ( y ). We therefore conclude that Own ( H , R , Γ ) = Own ( H , R (cid:48) , Γ (cid:48)(cid:48) ). Case
R-LetInt : (cid:96) D conf (cid:68) H , R , (cid:126)F , E [ let x = n in e ] (cid:69)(cid:68) H , R , (cid:126)F , E [ let x = n in e ] (cid:69) −→ D (cid:68) H , R { x (cid:48) (cid:55)→ n } , (cid:126)F , E [[ x (cid:48) / x ] e ] (cid:69) onSORT : Context- and Flow-Sensitive Ownership Refinement Types 53 By inversion (see
R-Deref ) we have that, for some Γ : Θ | (cid:126)(cid:96) | Γ, x : { ν : int | ν = n } (cid:96) e : τ ⇒ Γ (cid:48) Cons ( H , R , Γ ) x (cid:54)∈ dom ( Γ (cid:48) )We give that Γ (cid:48)(cid:48) = Γ, x (cid:48) : { ν : int | ν = n } , and it thus suffices to show that Θ | (cid:126)(cid:96) | Γ (cid:48)(cid:48) (cid:96) [ x (cid:48) / x ] e : τ ⇒ Γ (cid:48) and Cons ( H , R { x (cid:48) (cid:55)→ n } , Γ (cid:48)(cid:48) ). The first one is easyto obtain using the Lemma 10 (see R-Deref ) and the latter is trivial by similarreasoning to the
T-Let and
T-Deref cases.
Case
R-IfTrue : (cid:96) D conf (cid:68) H , R , (cid:126)F , E [ ifz y then e else e ] (cid:69)(cid:68) H , R , (cid:126)F , E [ ifz y then e else e ] (cid:69) −→ D (cid:68) H , R , (cid:126)F , E [ e ] (cid:69) By inversion (see
R-Deref ) we have that for some Γ : Γ ( x ) = { ν : int | ϕ } Θ | (cid:126)(cid:96) | Γ [ x ← (cid:45) { ν : int | ϕ ∧ ν = 0 } ] (cid:96) e : τ ⇒ Γ (cid:48) Cons ( H , R , Γ )We take Γ (cid:48)(cid:48) = Γ [ x ← (cid:45) { ν : int | ϕ ∧ ν = 0 } ], and want to show that Cons ( H , R , Γ (cid:48)(cid:48) )(that Θ | (cid:126)(cid:96) | Γ (cid:48)(cid:48) (cid:96) e : τ ⇒ Γ (cid:48) is immediate).By definition, from Cons ( H , R , Γ ) we have SAT ( H , R , Γ ), in particular x ∈ dom ( R ), R ( x ) ∈ Z and [ R ] [ R ( x ) /ν ] ϕ . The refinement predicates ϕ still holdsin the output environment, since nothing changes in the register after transition.Also from precondition of R-IfTrue , we have R ( x ) = 0, thus x satisfies therefinement that ν = 0. Thus [ R ] [ R ( x ) /ν ]( ϕ ∧ ν = 0) is trivially satisfied. Case
R-IfFalse : Similar to the case for
R-IfTrue . Case
R-MkRef : (cid:96) D conf (cid:68) H , R , (cid:126)F , E [ let x = mkref y in e ] (cid:69)(cid:68) H , R , (cid:126)F , E [ let x = mkref y in e ] (cid:69) −→ D (cid:68) H (cid:48) , R (cid:48) , (cid:126)F , E [[ x (cid:48) / x ] e ] (cid:69) a (cid:54)∈ dom ( H ) x (cid:48) (cid:54)∈ dom ( R ) H (cid:48) = H { a (cid:55)→ R ( y ) } R (cid:48) = R { x (cid:48) (cid:55)→ a } By inversion (see
R-Deref ) we have that for some Γ : (cid:126)(cid:96) (cid:96) WF ΓΓ ( y ) = τ + τ Θ | (cid:126)(cid:96) | Γ [ y ← (cid:45) τ ] , x : ( τ ∧ x x = y ) ref (cid:96) e : τ ⇒ Γ (cid:48) Cons ( H , R , Γ ) x (cid:54)∈ dom ( Γ (cid:48) )We give Γ (cid:48)(cid:48) = Γ [ y ← (cid:45) τ ] , x (cid:48) : ( τ ∧ x (cid:48) x (cid:48) = y ) ref , and must show that Θ | (cid:126)(cid:96) | Γ (cid:48)(cid:48) (cid:96) [ x (cid:48) / x ] e : τ ⇒ Γ (cid:48) and Cons ( H (cid:48) , R (cid:48) , Γ (cid:48)(cid:48) ). The first follows from Lemma 10and the reasoning found in R-Deref , and the second from the assumed well-formedness of τ + τ . It remains to show
Cons ( H (cid:48) , R (cid:48) , Γ (cid:48)(cid:48) ). To show that the output environmentis consistent, we must show that SATv ( H (cid:48) , R (cid:48) , R (cid:48) ( x (cid:48) ) , ( τ ∧ x (cid:48) x (cid:48) = y ) ref ) and SATv ( H (cid:48) , R (cid:48) , R (cid:48) ( y ) , τ ). By reasoning similar to that in R-Deref , it suffices toshow that
SATv ( H (cid:48) , R (cid:48) , R (cid:48) ( x (cid:48) ) , τ ref ) and SATv ( H (cid:48) , R (cid:48) , R (cid:48) ( y ) , τ ). We knowthat Cons ( H , R , Γ ), from which we have SAT ( H , R , Γ ), in particular y ∈ dom ( R ) and SATv ( H , R , R ( y ) , Γ ( y )). As R (cid:118) R (cid:48) and (cid:126)(cid:96) (cid:96) WF Γ , from Lemmas 17and 23, we have SATv ( H , R , R ( y ) , τ + τ ) implies SATv ( H , R (cid:48) , R (cid:48) ( y ) , τ + τ ).By Lemma 24, we then have SATv ( H (cid:48) , R (cid:48) , R ( y ) , τ + τ ). Then by Lemma 16,we have SATv ( H (cid:48) , R (cid:48) , v , τ ) and SATv ( H (cid:48) , R (cid:48) , v , τ ) where v = R ( y ). We thenhave SATv ( H (cid:48) , R (cid:48) , R (cid:48) ( x (cid:48) ) , τ ref ) and SATv ( H (cid:48) , R (cid:48) , R (cid:48) ( y ) , τ ) are satisfied.We must also show that the ownership invariant is preserved. Then, it’sto show ∀ a (cid:48) ∈ dom ( H ) . Own ( H (cid:48) , R (cid:48) , Γ (cid:48)(cid:48) )( a (cid:48) ) ≤
1. From
Cons ( H , R , Γ ) andLemmas 15 and 25 we have: Own ( H (cid:48) , R (cid:48) , Γ (cid:48)(cid:48) ) = Σ z ∈ dom ( Γ (cid:48)(cid:48) ) own ( H (cid:48) , R (cid:48) ( z ) , Γ (cid:48)(cid:48) ( z ))= Σ z ∈ dom ( Γ ) own ( H , R ( z ) , Γ ( z )) + { a (cid:55)→ } = Own ( H , R , Γ ) + { a (cid:55)→ } Since a (cid:54)∈ dom ( H ) and ∀ a (cid:48) ∈ dom ( H ) . Own ( H , R , Γ )( a (cid:48) ) ≤
1, we have ∀ a (cid:48) ∈ dom ( H ) . Own ( H (cid:48) , R (cid:48) , Γ (cid:48)(cid:48) )( a (cid:48) ) ≤ Case
R-Assign : (cid:96) D conf (cid:68) H , R , (cid:126)F , E [ y : = x ; e ] (cid:69)(cid:68) H , R , (cid:126)F , E [ y : = x ; e ] (cid:69) −→ D (cid:68) H (cid:48) , R (cid:48) , (cid:126)F , E [ e ] (cid:69) a = R ( y ) H (cid:48) = H { a ← (cid:45) R ( x ) } R (cid:48) = R By inversion (see the
R-Deref case) we have that Θ | (cid:126)(cid:96) | Γ [ x : τ + τ ][ y : τ (cid:48) ref ] (cid:96) y : = x ; e : τ ⇒ Γ (cid:48) Θ | (cid:126)(cid:96) | Γ [ x ← (cid:45) τ ][ y ← (cid:45) ( τ ∧ y y = τ x ) ref ] (cid:96) e : τ ⇒ Γ (cid:48) Cons ( H , R , Γ )We give Γ (cid:48)(cid:48) = Γ [ x ← (cid:45) τ ][ y ← (cid:45) ( τ ∧ y y = τ x ) ref ]. That Θ | (cid:126)(cid:96) | Γ (cid:48)(cid:48) (cid:96) e : τ ⇒ Γ (cid:48) is immediate.We must therefore show that Cons ( H (cid:48) , R (cid:48) , Γ (cid:48)(cid:48) ). To show that the outputenvironment is consistent, we must show that SATv ( H (cid:48) , R , R ( y ) , ( τ ∧ y y = x ) ref ) and SATv ( H (cid:48) , R , R ( x ) , τ ). By reasoning similar to that in R-Deref ,it suffices to show that
SATv ( H (cid:48) , R , R ( y ) , τ ref ) and SATv ( H (cid:48) , R , R ( x ) , τ ).From Cons ( H , R , Γ ), we know that SAT ( H , R , Γ ), in particular, SATv ( H , R , R ( x ) , Γ ( x )).If we show that own ( H , R ( x ) , τ + τ )( a ) = 0 and H ≈ a H (cid:48) , then, by Lemma 22,we will obtain SATv ( H (cid:48) , R , R ( x ) , τ + τ ), from which, by Lemma 16, SATv ( H (cid:48) , R , R ( x ) , τ )and SATv ( H (cid:48) , R , R ( x ) , τ ) follow. We then have SATv ( H (cid:48) , R , R ( y ) , τ ref ) and SATv ( H (cid:48) , R , R ( x ) , τ ) as H (cid:48) ( R ( y )) = R ( x ). (That any other variables z is consis-tent will follow from own ( H , R ( z ) , Γ ( z ))( a ) = 0 as proved below and lemma 22.) onSORT : Context- and Flow-Sensitive Ownership Refinement Types 55 To show own ( H , R ( x ) , τ + τ )( a ) = 0, we define O (cid:48) , O (cid:48)(cid:48) , O (cid:48) and O (cid:48)(cid:48) as below: Own ( H , R , Γ ) = O (cid:48) + O (cid:48)(cid:48) Own ( H (cid:48) , R , Γ (cid:48)(cid:48) ) = O (cid:48) + O (cid:48)(cid:48) O (cid:48) = Σ z ∈ dom ( Γ ) \{ y , x } own ( H , R ( z ) , Γ ( z )) O (cid:48)(cid:48) = own ( H , R ( y ) , Γ ( y )) + own ( H , R ( x ) , Γ ( x )) O (cid:48) = Σ z ∈ dom ( Γ (cid:48)(cid:48) ) \{ y , x } own ( H (cid:48) , R ( z ) , Γ (cid:48)(cid:48) ( z )) O (cid:48)(cid:48) = own ( H (cid:48) , R ( y ) , Γ (cid:48)(cid:48) ( y )) + own ( H (cid:48) , R ( x ) , Γ (cid:48)(cid:48) ( x ))By the definition of the ownership function, Γ ( y ) = τ (cid:48) ref and Γ ( x ) = τ + τ ,we have: O (cid:48)(cid:48) = own ( H , H ( R ( y )) , τ (cid:48) ) + { a (cid:55)→ } + own ( H , R ( x ) , τ + τ ) O (cid:48)(cid:48) = own ( H (cid:48) , H (cid:48) ( R ( y )) , τ ) + { a (cid:55)→ } + own ( H (cid:48) , R ( x ) , τ )As Own ( H , R , Γ )( a ) ≤ Cons ( H , R , Γ )) and from Own ( H , R , Γ )( a ) = O (cid:48) ( a ) + O (cid:48)(cid:48) ( a )= O (cid:48) ( a ) + own ( H , H ( R ( y )) , τ (cid:48) )( a ) + 1 + own ( H , R ( x ) , τ + τ )( a )= 1we have that: own ( H , H ( R ( y )) , τ (cid:48) )( a ) = own ( H , R ( x ) , τ + τ )( a )= O (cid:48) ( a ) = 0We now show that H ≈ a H (cid:48) . The first two conditions are clear, so it remainsto show that, for any n , H (cid:96) a ⇓ n iff H (cid:48) (cid:96) a ⇓ n . From Lemma 20, we have H (cid:96) a ⇓ | τ (cid:48) ref | , and a proof by contradiction gives that | τ (cid:48) ref | is the onlysuch n for which H (cid:96) a ⇓ n . We now argue the forward case for the bi-implication,the backwards case follows similar reasoning.Given H (cid:96) a ⇓ | τ (cid:48) ref | , we must show H { a ← (cid:45) R ( x ) } (cid:96) a ⇓ | τ ref | , forwhich it suffices to show H { a ← (cid:45) R ( x ) } (cid:96) R ( x ) ⇓ | τ | . From our requirementthat τ (cid:48) and τ (and therefore τ + τ ) have similar shapes, we have | τ (cid:48) | = | τ | = | τ + τ | . By inverting the well-typing of the input configuration, we must have SATv ( H , R , R ( x ) , τ + τ ), thus by Lemma 20 we must have H (cid:96) R ( x ) ⇓ | τ | .As | τ | = | τ (cid:48) | < | τ (cid:48) ref | , a cannot be reachable from R ( x ) in H (otherwise wewould have a reaches an integer along multiple heap paths of differing lengths, aclear contradiction). Then the value of a in H is irrelevant to the derivation of H (cid:96) R ( x ) ⇓ | τ | , whereby H { a ← (cid:45) R ( x ) } (cid:96) R ( x ) ⇓ | τ | must hold.Then, it’s to show ∀ a (cid:48) ∈ dom ( H (cid:48) ) . Own ( H (cid:48) , R , Γ (cid:48)(cid:48) )( a (cid:48) ) = ( O (cid:48) + O (cid:48)(cid:48) )( a (cid:48) ) = O (cid:48) ( a (cid:48) )+ O (cid:48)(cid:48) ( a (cid:48) ) ≤
1. For every z ∈ dom ( Γ ) \{ y , x } (and similarly for Γ (cid:48)(cid:48) ), we have Γ ( z ) = Γ (cid:48)(cid:48) ( z ). Further, from O (cid:48) ( a ) = 0 above, we must have own ( H , R ( z ) , Γ ( z ))( a ) =0 for all such z . As H ≈ a H (cid:48) , by Lemma 19, we have that O (cid:48) = O (cid:48) . Then, from ∀ a (cid:48) ∈ dom ( H ) . Own ( H , R , Γ )( a (cid:48) ) = O (cid:48) ( a (cid:48) ) + O (cid:48)(cid:48) ( a (cid:48) ) ≤
1, it suffices to showthat ∀ a (cid:48) ∈ dom ( H ) . O (cid:48)(cid:48) ( a (cid:48) ) ≤ O (cid:48)(cid:48) ( a (cid:48) ). We first consider the case for a : O (cid:48)(cid:48) ( a ) = own ( H (cid:48) , H (cid:48) ( R ( y )) , τ )( a ) + own ( H (cid:48) , R ( x ) , τ )( a ) + 1 O (cid:48)(cid:48) ( a ) = own ( H , R ( x ) , τ + τ )( a ) + own ( H , H ( R ( y )) , τ (cid:48) )( a ) + 1From above, we have own ( H , R ( x ) , τ + τ )( a ) = own ( H , H ( R ( y )) , τ (cid:48) )( a ) = 0.By Lemma 19 and H ≈ a H (cid:48) , we have own ( H , R ( x ) , τ + τ ) = own ( H (cid:48) , R ( x ) , τ + τ ). Also by Lemma 15, we have own ( H (cid:48) , R ( x ) , τ + τ ) = own ( H (cid:48) , R ( x ) , τ ) + own ( H (cid:48) , R ( x ) , τ ). From H (cid:48) ( R ( y )) = R ( x ), we therefore have own ( H (cid:48) , H (cid:48) ( R ( y )) , τ )( a ) = own ( H (cid:48) , R ( x ) , τ )( a ) = 0, and thus: O (cid:48)(cid:48) ( a ) = own ( H (cid:48) , H (cid:48) ( R ( y )) , τ )( a ) + own ( H (cid:48) , R ( x ) , τ )( a ) + 1 = 1 = O (cid:48)(cid:48) ( a )Next, consider some a (cid:54) = a (cid:48) ; O (cid:48)(cid:48) ( a (cid:48) ) = own ( H (cid:48) , H (cid:48) ( R ( y )) , τ )( a (cid:48) ) + own ( H (cid:48) , R ( x ) , τ )( a (cid:48) ) O (cid:48)(cid:48) ( a (cid:48) ) = own ( H , R ( x ) , τ + τ )( a (cid:48) ) + own ( H , H ( R ( y )) , τ (cid:48) )( a (cid:48) )By reasoning similar to the case for a = a (cid:48) , we have O (cid:48)(cid:48) ( a (cid:48) ) ≤ own ( H , R ( x ) , τ + τ )( a (cid:48) ) ≤ O (cid:48)(cid:48) ( a (cid:48) ). We therefore conclude that ∀ a (cid:48) ∈ dom ( H (cid:48) ) . Own ( H (cid:48) , R , Γ (cid:48)(cid:48) )( a (cid:48) ) ≤ Case
R-Alias : (cid:96) D conf (cid:68) H , R , (cid:126)F , E [ alias ( x = y ) ; e ] (cid:69)(cid:68) H , R , (cid:126)F , E [ alias ( x = y ) ; e ] (cid:69) −→ D (cid:68) H , R , (cid:126)F , E [ e ] (cid:69) R ( x ) = R ( y )By inversion (see R-Deref ) we have for some Γ that: Θ | (cid:126)(cid:96) | Γ [ x : τ ref r ][ y : τ ref r ] (cid:96) alias ( x = y ) ; e : τ ⇒ Γ (cid:48) Θ | (cid:126)(cid:96) | Γ [ x ← (cid:45) τ (cid:48) ref r (cid:48) ][ y ← (cid:45) τ (cid:48) ref r (cid:48) ] (cid:96) e : τ ⇒ Γ (cid:48) τ ref r + τ ref r ≈ τ (cid:48) ref r (cid:48) + τ (cid:48) ref r (cid:48) Cons ( H , R , Γ )We give Γ (cid:48)(cid:48) = Γ [ x ← (cid:45) τ (cid:48) ref r (cid:48) ][ y ← (cid:45) τ (cid:48) ref r (cid:48) ], and must show Θ | (cid:126)(cid:96) | Γ (cid:48)(cid:48) (cid:96) e : τ ⇒ Γ (cid:48) and Cons ( H , R , Γ (cid:48)(cid:48) ). The first is immediate.To show Cons ( H , R , Γ (cid:48)(cid:48) ) we first define: τ p = τ ref r τ p = τ ref r τ q = τ (cid:48) ref r (cid:48) τ q = τ (cid:48) ref r (cid:48) τ q = τ q + τ q τ p = τ p + τ p We thus have τ q ≈ τ p . onSORT : Context- and Flow-Sensitive Ownership Refinement Types 57 We know that
Cons ( H , R , Γ ), from which we have SAT ( H , R , Γ ), in particu-lar SATv ( H , R , R ( y ) , Γ ( y ) = τ ref r ) and SATv ( H , R , R ( x ) , Γ ( x ) = τ ref r ).From τ p + τ p = τ p and Lemma 16, we have SATv ( H , R , v , τ p ) and SATv ( H , R , v , τ p )imply SATv ( H , R , v , τ p ), where v = H ( R ( y )) = H ( R ( x )). From τ q ≈ τ p andLemma 13, we have that SATv ( H , R , v , τ p ) implies SATv ( H , R , v , τ q ). FromLemma 16 we also have that SATv ( H , R , v , τ q ) implies SATv ( H , R , v , τ q ) and SATv ( H , R , v , τ q ), where again v = H ( R ( y )) = H ( R ( x )).Then from the reasoning above, the refinements of τ q and τ q are valid and Cons ( H , R , Γ (cid:48)(cid:48) ) holds.Then, it’s to show ∀ a ∈ dom ( H ) . Own ( H , R , Γ (cid:48)(cid:48) )( a ) ≤
1. To prove that
Own ( H , R , Γ ) = Own ( H , R , Γ (cid:48)(cid:48) ) follows from: own ( H , R ( x ) , τ ref r ) + own ( H , R ( y ) , τ ref r ) = own ( H , R ( x ) , τ (cid:48) ref r (cid:48) ) + own ( H , R ( y ) , τ (cid:48) ref r (cid:48) )which follows immediately from the conditions τ ref r + τ ref r ≈ τ (cid:48) ref r (cid:48) + τ (cid:48) ref r (cid:48) , R ( x ) = R ( y ), and Lemmas 14 and 15. Case
R-AliasPtr : By reasoning similar to the
R-Alias case.
Case
R-AliasFail,R-AliasPtrFail : The result configuration
AliasFail is trivially well-typed.
Case
R-Assert : (cid:96) D conf (cid:68) H , R , (cid:126)F , E [ assert ( ϕ ) ; e ] (cid:69) Γ | = [ R ] ϕ (cid:68) H , R , (cid:126)F , E [ assert ( ϕ ) ; e ] (cid:69) −→ D (cid:68) H , R , (cid:126)F , E [ e ] (cid:69) By inversion (see
R-Deref ) we can obtain Θ | (cid:126)(cid:96) | Γ (cid:96) assert ( ϕ ) ; e : τ ⇒ Γ (cid:48) and Θ | (cid:126)(cid:96) | Γ (cid:96) e : τ ⇒ Γ (cid:48) , and the result follows immediately by taking Γ (cid:48)(cid:48) = Γ . Case
R-AssertFail : (cid:96) D conf (cid:68) H , R , (cid:126)F , E [ assert ( ϕ ) ; e ] (cid:69)(cid:68) H , R , (cid:126)F , E [ assert ( ϕ ) ; e ] (cid:69) −→ D AssertFail Θ | (cid:126)(cid:96) | Γ (cid:96) assert ( ϕ ) ; e : τ ⇒ Γ (cid:48) By inversion (see the
R-Deref case) we have that Γ | = ϕ , i.e., | = (cid:74) Γ (cid:75) = ⇒ ϕ ,for some Γ such that Cons ( H , R , Γ ). From Lemma 11 we therefore have | =[ R ] (cid:74) Γ (cid:75) . From the precondition of R-AssertFail we have that (cid:54)| = [ R ] ϕ . Butfrom | = (cid:74) Γ (cid:75) = ⇒ ϕ and | = [ R ] (cid:74) Γ (cid:75) we can conclude that | = [ R ] ϕ , yielding acontradiction. We therefore conclude that this case is impossible. Case
R-Call : (cid:96) D conf (cid:68) H , R , (cid:126)F , E [ let x = f (cid:96) ( y , . . . , y n ) in e (cid:48) ] (cid:69) f (cid:55)→ ( x , .. , x n ) e ∈ D (cid:68) H , R , (cid:126)F , E [ let x = f (cid:96) ( y , . . . , y n ) in e (cid:48) ] (cid:69) −→ D (cid:68) H , R , E [ let x = [] (cid:96) in e (cid:48) ] : (cid:126)F , [ y / x ] · · · [ y n / x n ] e (cid:69) We must show that (cid:96) D conf (cid:68) H , R , E [ let x = [] (cid:96) in e (cid:48) ] : (cid:126)F , [ y / x ] · · · [ y n / x n ] e (cid:69) forsome Γ (cid:48)(cid:48) . By inversion on the configuration typing, we have that, for some Γ : Θ | (cid:126)(cid:96) | Γ (cid:96) E [ let x = f (cid:96) ( y , . . . , y n ) in e (cid:48) ] : τ n ⇒ Γ n . By Lemma 7, we then have for some τ , and Γ (cid:48) that: Θ | (cid:126)(cid:96) | Γ (cid:96) let x = f (cid:96) ( y , . . . , y n ) in e (cid:48) : τ ⇒ Γ (cid:48) Θ | [] : τ ⇒ Γ (cid:48) | (cid:126)(cid:96) (cid:96) ectx E : τ n ⇒ Γ n Taking τ = τ, Γ = Γ (cid:48) , Γ = Γ, Γ = Γ n , τ = τ n , by Lemma 28 we have, forsome τ (cid:48)(cid:48)(cid:48) , Γ (cid:48)(cid:48)(cid:48) : Θ | (cid:96) : (cid:126)(cid:96) | Γ (cid:96) σ x e : τ (cid:48)(cid:48)(cid:48) ⇒ Γ (cid:48)(cid:48)(cid:48) Θ | [] : τ (cid:48)(cid:48)(cid:48) ⇒ Γ (cid:48)(cid:48)(cid:48) | (cid:126)(cid:96) (cid:96) ectx E [ let x = [] (cid:96) in e (cid:48) ] : τ n ⇒ Γ n where: σ x = [ y / x ] · · · [ y n / x n ] Θ ( f ) = ∀ λ. (cid:104) x : τ i , . . . , x n : τ n (cid:105) → (cid:104) x : τ (cid:48) , . . . , x n : τ (cid:48) n | τ p (cid:105) We therefore take Γ (cid:48)(cid:48) = Γ .We must also prove that ∀ i ∈ { ..n + 1 } .Θ | [] : τ i ⇒ Γ i | (cid:126)(cid:96) i − (cid:96) ectx E (cid:48) i − : τ i − ⇒ Γ i − where E (cid:48) n = E [ let x = [] (cid:96) in e (cid:48) ] and E (cid:48) i = E i (0 ≤ i < n ), which can bedivided into proving ∀ i ∈ { ..n } .Θ | [] : τ i ⇒ Γ i | (cid:126)(cid:96) i − (cid:96) ectx E (cid:48) i − : τ i − ⇒ Γ i − and Θ | [] : τ n +1 ⇒ Γ n +1 | (cid:126)(cid:96) n (cid:96) ectx E (cid:48) n : τ n ⇒ Γ n . The first follows by inversionon (cid:96) D conf (cid:68) H , R , (cid:126)F , E [ let x = f (cid:96) ( y , . . . , y n ) in e (cid:48) ] (cid:69) . To show the latter, we define Γ n +1 = Γ (cid:48)(cid:48)(cid:48) and τ n +1 = τ (cid:48)(cid:48)(cid:48) , whereby the well-typing holds from the result ofapplying Lemma 28 above.Finally, Cons ( H , R , Γ (cid:48)(cid:48) ) follows immediately from Cons ( H , R , Γ ) and Γ (cid:48)(cid:48) = Γ . D Proof of Progress
We first state the standard decomposition lemma.
Lemma 29 (Decomposition).
For any term e, either e = x for some x orthere exists some E and e (cid:48) where E [ e (cid:48) ] = e and one of the following cases hold:1. e (cid:48) = let x = mkref y in e (cid:48)(cid:48)
2. e (cid:48) = let x = y in e (cid:48)(cid:48)
3. e (cid:48) = let x = n in e (cid:48)(cid:48)
4. e (cid:48) = let x = ∗ y in e (cid:48)(cid:48)
5. e (cid:48) = let x = f (cid:96) ( y , . . . , y n ) in e (cid:48)(cid:48)
6. e (cid:48) = x ; e (cid:48)(cid:48)
7. e (cid:48) = alias ( x = y ) ; e (cid:48)(cid:48)
8. e (cid:48) = alias ( x = ∗ y ) ; e (cid:48)(cid:48) onSORT : Context- and Flow-Sensitive Ownership Refinement Types 59
9. e (cid:48) = ifz x then e else e
10. e (cid:48) = assert ( ϕ ) ; e (cid:48)(cid:48)
11. e (cid:48) = x : = y ; eProof. Straightforward induction on e . Proof (Progress; Lemma 4).
By inversion on (cid:96) D conf C , either C = AliasFail or C = (cid:68) H , R , (cid:126)F , e (cid:69) . In the former case the result is immediate. In the latter casewe have that Θ | (cid:126)(cid:96) | Γ (cid:96) e : τ ⇒ Γ (cid:48) for some τ, Γ and Γ (cid:48) , and further fromLemma 29, we have that either e = x for some x or there exists some E or e (cid:48) where e = E [ e (cid:48) ] and e (cid:48) meets one of the cases in Lemma 29.In the case e = x , we further make case analysis on the form of (cid:126)F . The casewhere (cid:126)F = (cid:15) is immediate; In the other case where (cid:126)F = F : (cid:126)F (cid:48) , the configurationcan step to (cid:68) H , R , (cid:126)F , F [ x ] (cid:69) according to R-Var .For the remaining cases where e = E [ e (cid:48) ], by the well-typing of e with respectto Γ and Lemma 7, we have that Θ | L | Γ (cid:96) e (cid:48) : τ ⇒ Γ some τ and Γ .We now treat the remaining forms of e (cid:48) Case: e (cid:48) = let x = ∗ y in e (cid:48)(cid:48) By inversion (Lemma 6) and Lemma 12 we must have that for some Γ p where Cons ( H , R , Γ p ) that y ∈ dom ( Γ p ) and Γ p ( y ) = τ (cid:48) ref r . From Cons ( H , R , Γ p )we must have y ∈ dom ( R ) and further SATv ( H , R , R ( y ) , τ (cid:48) ref r (cid:48) ), from which wemust have R ( y ) = a and a ∈ dom ( H ). Then C can step according to R-Deref . Case: e (cid:48) = let x = y in e (cid:48)(cid:48) Again, by Lemmas 6 and 12 and the definition of
Cons , we must have that y ∈ dom ( R ), and the system can step according to R-LetVar . Case: e (cid:48) = let x = mkref y in e (cid:48)(cid:48) Similar to the
R-LetVar case above.
Case: e (cid:48) = let x = n in e (cid:48)(cid:48) e (cid:48) = x ; e (cid:48)(cid:48) e (cid:48) = assert ( ϕ ) ; e (cid:48)(cid:48) The first two can trivially step according to
R-LetInt and
R-Seq respectively.the last can step according to
R-Assert or R-AssertFalse (although by Lem-mas 2 and 3 the latter is impossible).
Case: e (cid:48) = alias ( x = y ) ; e (cid:48)(cid:48) Again by Lemmas 6 and 12 and that
Cons ( H , R , Γ p ) implies x and y are boundto addresses in the register file, we have that the configuration can step accordingto R-Alias or R-AliasFail . Case: e (cid:48) = alias ( x = ∗ y ) ; e (cid:48)(cid:48) Similar to the case above, we must have that x is bound to an address in theregister file, and that y is bound to an address that is itself mapped to an addressin the heap H . Then the configuration may step according to R-AliasPtr or R-AliasPtrFail