SS.-W. Lin and L. Petrucci (Eds.): 2nd French SingaporeanWorkshop on Formal Methods and ApplicationsEPTCS 156, 2014, pp. 45–51, doi:10.4204/EPTCS.156.8 c (cid:13)
Asankhaya SharmaThis work is licensed under theCreative Commons Attribution License.
Verified Subtyping with Traits and Mixins
Asankhaya Sharma
Department of Computer ScienceNational Univeristy of Singapore [email protected]
Traits allow decomposing programs into smaller parts and mixins are a form of composition thatresemble multiple inheritance. Unfortunately, in the presence of traits, programming languages likeScala give up on subtyping relation between objects. In this paper, we present a method to checksubtyping between objects based on entailment in separation logic. We implement our method as adomain specific language in Scala and apply it on the Scala standard library. We have verified that67% of mixins used in the Scala standard library do indeed conform to subtyping between the traitsthat are used to build them.
Traits [8] have been recognized as a mechanism to support fine grained reuse in programming. Sev-eral programming languages (Scala, Fortress, Ruby, etc.) support the use of traits in some form orother. Traits and mixins provide support for code reuse and composition that goes beyond classes andinheritance in object oriented programs. In addition, object oriented (OO) programs themselves are no-toriously hard to verify in a modular fashion. Recently [4, 11, 6] separation logic based approach hasyielded success in verification of object oriented programs. This include support for verifying inheritanceand behavior subtyping, in conformance with OO paradigm. In this paper, we extend the work done onverification of OO programs in separation logic to verify subtyping with traits and mixins.Below we consider an example that illustrates the problem of subtyping with traits and mixins. The
ICell trait captures an object with an integer value that can be accessed with get and set methods. The
BICell trait provides a basic implementation for
ICell , while the
Double and
Inc traits extend the
ICell trait by doubling and incrementing the integer value respectively.trait
ICell { def get () : Int def set ( x : Int ) } trait BICell extends
ICell { private var x : Int = get () { x } def set ( x : Int ) { this . x = x }} trait Double extends
ICell { abstract override def set ( x : Int ) { super . set ( ∗ x ) }} trait Inc extends
ICell { abstract override def set ( x : Int ) { super . set ( x + ) }} These traits are used in the following class mixins. The integer value field of the objects of
OddICell mixin is always odd, while the value is even for objects of
EvenICell mixin. class
OddICell extends
BICell with
Inc with
Double class
EvenICell extends
BICell with
Double with
Inc m ( c : BICell with
Inc with
Double ) : Int = { c . get } val oic = new OddICell val eic = new EvenICellm ( oic ) // Validm ( eic ) // Valid
The method m can be called with an object of both mixins EvenICell and
OddICell , even thoughthe expected object (c) type is a supertype of
OddICell and not
EvenICell . Thus, the type system inScala cannot distinguish between the two calls made to method m as it does not check for subtypingbetween the objects. The key contribution of this paper is to present a method for checking subtypingin the presence of traits and mixins in Scala. In section 2, we present an approach based on entailmentin separation logic to verify subtyping. In section 3, we present a domain specific language which isembedded in Scala and can support verified subtyping with traits and mixins. We apply our technique tothe mixin class hierarchies in the Scala standard library and verify subtyping in 67% of the traits as shownin section 4. Our complete development including the source code of the domain specific language andall examples are available on-line at the following URL. http://loris-7.ddns.comp.nus.edu.sg/˜project/SLEEKDSL/ We consider a core language based on [4] for formalizing our approach. As shown in figure 1, to simplifythe presentation we focus only on type information for traits and mixins while ignoring all other featuresin our core language. We also assume that all classes are part of mixin compositions and only traits areused to create mixins. Since, existing approaches [4] can handle class based single inheritance, we focusonly on mixin compositions in this paper. The rest of the constructs in the core language are relatedto predicates ( F ) in separation logic. Each trait (and mixin) C can be represented by a correspondingpredicate C h v ∗ i . mixin :: = class C [ extends C ] [ with C ] ∗ pred :: = C h v ∗ i ≡ F [ inv p ] F :: = W ( ∃ w ∗ · k ∧ p ) ∗ k :: = emp | C h v ∗ i | k ∗ k p :: = a | p ∧ p a :: = b | ¬ bb :: = v = v | v = null | a ≤ | a = a :: = k | k × v | a + a Figure 1: Core Language for Traits and MixinsPredicates based on separation logic are sufficient to specify mixins because of class linearization inScala [10]. After class linearization a mixin class composition (unlike multiple inheritance) has a singlelinear hierarchy. In the case of our running example, the mixins give rise to the following linearizations:sankhaya Sharma 47
OddICell ← Double ← Inc ← BICellOddICell h this i ≡ BICell h this , v i ∗ Inc h v , v i ∗ Double h v , null i EvenICell ← Inc ← Double ← BICellEvenICell h this i ≡ BICell h this , v i ∗ Double h v , v i ∗ Inc h v , null i A mixin class composition can be treated as a single inheritance hierarchy based on the linearizationand thus, subtyping between the mixins can be decided by checking the entailment based on separationlogic predicates. In case of our running example, the call to method m is valid with oic object but not the eic object as the following entailments show. OddICell h oic i ⊢ BICell h c , v i ∗ Inc h v , v i ∗ Double h v , null i ValidEvenICell h eic i ⊢ BICell h c , v i ∗ Inc h v , v i ∗ Double h v , null i Invalid
We now show how the problem of checking subtyping between objects belonging to two different mixinsis reduced to an entailment between the corresponding predicates in separation logic. This entailmentcan be checked with the help of existing solvers for separation logic (like SLEEK [3]). The entailmentrule for checking subtyping with traits and mixins is given in figure 2. An object of mixin C is a subtypeof mixin D when the entailment between their corresponding predicates in separation logic is valid. [ ENT − Subtype − Check ] class C [ extends C ] [ with C ] ∗ class D [ extends D ] [ with D ] ∗ C h this , v i [ ∗ C h v , v i ] ∗ ⊢ D h this , u i [ ∗ D h u , u i ] ∗ C < : D Figure 2: Checking Subtyping with EntailmentEntailment checking in separation logic can be used to decide subtyping with traits and mixins. Butin order to integrate subtyping support inside Scala we face some engineering challenges. In particular,it is too restrictive and infeasible to do this kind of checking for all the mixins. This requires supportfor selective subtyping as all mixins will not satisfy the subtype relation. In order to provide the pro-grammer the choice of checking subtyping usage in their methods we have implemented an embeddeddomain specific language (DSL) in Scala. This DSL uses the SLEEK entailment checker for checkingthe validity of entailments in separation logic. In the next section we describe the SLEEK DSL and howit is integrated in Scala.
Our proposal is based on embedding a domain specific language (SLEEK DSL) in Scala. As shownin figure 3, a Scala library (SLEEK lib) interfaces directly with the external application - the SLEEKentailment prover. In addition, we extend Scala with a DSL (SLEEK DSL) which makes use of the Scalalibrary to provide the entailment checking feature inside Scala programs. Further, for using with theScala interpreter we provide an interactive mode (SLEEK inter) which uses the SLEEK DSL and libraryto enable interactive entailment proving. Thus, the implementation of the verified subtyping in Scalawith SLEEK has three main components:8 Verified Subtyping with Traitsand MixinsFigure 3: Overview of SLEEK DSL − a Scala library that supports all SLEEK interactions − a domain specific language (DSL) implemented in Scala that models the SLEEK input language.With this DSL we get for free embedded type checking in Scala. − a helper library designed for the Scala interpreter. The library runs SLEEK in interactive mode inthe background to provide seamless integration with Scala.In short, the SLEEK library provides basic functionality for constructing Scala objects representingseparation logic formulas. The entailment checking method is in fact the actual front-end for SLEEK.It takes two Scala objects representing separation logic formulas, translates them to the SLEEK inputlanguage and invokes SLEEK. The result and the possible residue is captured and parsed using the Scalaparser combinator library to extract the Scala representation. To facilitate a better syntax for writingformulas and support for richer interplay with the Scala types we present a domain specific language,SLEEK DSL implemented on top of the Scala library. We will outline the SLEEK DSL by presentinghow an entailment checking can be encoded in our DSL. As an example consider the following entailment check between two separation logic formulas definedusing SLEEK DSL. val r = x:: node h , null i ⊢ x:: ll h m i && m === node . The second formula describes a state in which x is the root pointer of for adata structure described by the ll predicate. This predicate abstracts a linked list of size m.SLEEK DSL relies on the functions defined in the SLEEK Library to create new easy to use operatorsthat provide a more user friendly syntax. A special operator, the double colon (::) is used to describe thepoints-to relation commonly used for heap nodes. It also provides the usual arithmetic (e.g. + , − ) andboolean (e.g. &&, || , === , ! == , ⊢ ) operators to help in constructing the separation logic formula. Thenotation used in the DSL is similar to the one used for SLEEK in [3]. The use of a DSL allows easyintermixing of SLEEK formulas with other Scala types. We use implicit conversions between types (e.g.from scala . Int to formula [ IntSort ] ) to make it even easier to use these formulas in Scala programs.Furthermore, our library provides a definition for the isValid method in the formula class. In orderto check the validity of the above entailment it is sufficient to call r . isValid which feeds the entailmentto SLEEK and converts the result back into a scala . Boolean for use as a conditional. Implicit methodsprovide an easy mechanism to convert from one type of object to the desired type. This enables thesankhaya Sharma 49support for a SLEEK like syntax within Scala. Formulas allow for a variety of types for the parametersused (such as x and m ). In the Scala library these types are grouped under the following type hierarchy.sealed trait Top trait
BoolSort extends
Top trait
IntSort extends
Top trait
BagSort extends
Top trait
ShapeSort extends
Top trait
Bottom extends
BoolSort with
IntSort with
BagSort with
ShapeSort
This trait allows the embedding of the types used in the separation logic formula as Scala types. Bydefining the various operators using these types, soft type checking for SLEEK formulas is automaticallyensured by the underlying Scala type system. The benefit of using a DSL is that it provides a simplersyntax and familiar look and feel for the user of the library. The formula represented by the DSL is alsomuch more concise.The SLEEK DSL allows programmers to verify entailments written in separation logic. In addition,programmers can use the DSL to encode subtyping check as an entailment check in separation logic asdescribed in section 2.
The Scala runtime provides a good interpreter for rapid prototyping which can be used from the commandline. Similarly, SLEEK also has an interactive mode in which it accepts commands and gives the resultsback to command line. In order to make SLEEK’s interactive mode available to the Scala interpreter,we provide a helper library that hides the extra intricacies incurred by using SLEEK interactively. Thebenefit of using the interactive mode is that the user defined predicates and data types will not be definedagain with each call to isValid method. This makes the interactive mode of SLEEK DSL faster whencompared to calling the same function from the basic SLEEK library.Our implementation for verified subtyping integrates into Scala as an API (SLEEK library), as alanguage (SLEEK DSL) and as an interpreter (SLEEK Interactive mode). This provides programmersthe ability to use our procedure in different ways as desired.
We have used SLEEK DSL to verify subtyping of mixin compositions from the Scala standard library. Tothe best of our knowledge this it the first such study of subtyping in Scala. The following table presentsthe results. The first column is the name of the class hierarchy. The second column lists the total numberof mixins in the hierarchy, while the third column gives the number of mixins for which we can verifythat the subtyping relation holds. The last column gives the percentage of mixins with subtyping.
Class Hierarchy Total Num of Mixins Mixins with Subtyping PercentageExceptions
11 11 100
Maths
Parser Combinator
Collections
27 12 44
Total
49 33 670 Verified Subtyping with Traitsand MixinsAs an example of mixin hierarchy whose subtyping relations are verified consider the following whichrepresents the maths library in Scala. The only mixin which breaks the subtyping relation is PartialOrdering.Rest of the mixins can be verified to respect the expected subtyping. Thus we have verified that subtypingholds for 4 out of 5 mixins that are part of math class hierarchy.Equiv is SUPERTYPE of PartialOrderingPartialOrdering is NOT SUPERTYPE of OrderingOrdering is SUPERTYPE of NumericNumeric is SUPERTYPE of IntegralNumeric is SUPERTYPE of Fractional
The work that comes closest to our method for checking subtyping is the work of Bierman et.al [2], theyprovide a mechanism to use SMT solvers for deciding subtyping in a first order functional language. Onthe other hand, we use SLEEK an entailment checker for separation logic to decide subtyping betweentraits and mixins. SMT solvers have also been used [1] for verifying typing constraints. Similar to ourimplementation of SLEEK DSL, the
Scala Z proposal of K ¨oksal et. al [9] integrates the Z3 SMT solverinto Scala. Although the integration is similar, the two solvers have different focuses: Z3 is a generalSMT solver, while SLEEK is a prover for separation logic.Another line of work is on specification and verification of traits and mixins. Damiani et. al exploretrait verification in [5]. They observe the need for multiple specifications and introduce the concept ofproof outline. They support a trait based language with limited composition - symmetric sum of traits andtrait alteration. Our work does not directly address the issue of trait verification but checking subtypingis essential part of OO verification using separation logic [4]. We believe that dynamic specificationsof [4] along with verified subtyping can be used to verify traits and mixins. Behavior subtyping is astronger notion of subtyping between objects. The approach of lazy behavioral subtyping [7] can supportincremental verification of classes in presence of multiple inheritance. However, this is overly restrictivefor mixin compositions in Scala and our method provides a more flexible support for subtyping in Scala. In this paper, we presented a method to enable verified subtyping in Scala. Our method is based ona reduction to entailment checking in separation logic. We implemented a domain specific language(SLEEK DSL) in Scala to enable programmers to check subtyping in their programs. Using SLEEKDSL we carried out a study of the Scala standard library and verified that 67% of the mixins werecomposed of traits that are in a subtyping relation.
Acknowledgements
We thank Shengyi Wang for his prompt and useful feedback on the paper. Cristian Gherghina and ChinWei Ngan provided valuable comments and suggestions on an early presentation of this work.sankhaya Sharma 51
References [1] Michael Backes, C˘at˘alin Hrit¸cu & Thorsten Tarrach (2011):
Automatically verifying typing constraints fora data processing language . In: Certified Programs and Proofs, Springer, pp. 296–313, doi: .[2] Gavin M. Bierman, Andrew D. Gordon, C˘at˘alin Hrit¸cu & David Langworthy (2010):
Semantic Subtypingwith an SMT Solver . ICFP ’10, pp. 105–116, doi: .[3] Wei-Ngan Chin, Cristina David & Cristian Gherghina (2011):
A HIP and SLEEK verification system . In:SPLASH, pp. 9–10, doi: .[4] Wei-Ngan Chin, Cristina David, Huu Hai Nguyen & Shengchao Qin (2008):
Enhancing modular OO verifi-cation with separation logic . In: POPL, pp. 87–99, doi: .[5] Ferruccio Damiani, Johan Dovland, Einar Broch Johnsen & Ina Schaefer (2011):
Verifying traits: a proofsystem for fine-grained reuse . In: FTfJP, pp. 8:1–8:6, doi: .[6] Dino Distefano & Matthew J. Parkinson (2008): jStar: towards practical verification for java . In: OOPSLA,pp. 213–226, doi: .[7] Johan Dovland, Einar Broch Johnsen, Olaf Owe & Martin Steffen (2011):
Incremental reasoning with lazybehavioral subtyping for multiple inheritance . Sci. Comput. Program., doi: .[8] St´ephane Ducasse, Oscar Nierstrasz, Nathanael Sch¨arli, Roel Wuyts & Andrew P. Black (2006):
Traits: Amechanism for fine-grained reuse . ACM Trans. Program. Lang. Syst. 28(2), pp. 331–388, doi: .[9] Ali Sinan K¨oksal, Viktor Kuncak & Philippe Suter (2011):
Scala to the power of Z3: integrating SMT andprogramming . In: CADE, pp. 400–406, doi: .[10] Martin Odersky, Philippe Altherr, Vincent Cremet, Iulian Dragos, Gilles Dubochet, Burak Emir, SeanMcDirmid, Stphane Micheloud, Nikolay Mihaylov, Michel Schinz, Erik Stenman, Lex Spoon & MatthiasZenger (2006):
An Overview of the Scala Programming Language . Technical Report, EPFL.[11] Matthew J. Parkinson & Gavin M. Bierman (2008):
Separation logic, abstraction and inheritance . In: POPL,pp. 75–86, doi:10.1145/1328438.1328451