Abstract

A new approach for programming that enables switching among contexts of commands during program execution is context-oriented programming (COP). This technique is more structured and modular than object-oriented and aspect-oriented programming and hence more flexible. For context-oriented programming, as implemented in COP languages such as ContextJ* and ContextL, this paper introduces accurate operational semantics. The language model of this paper uses Java concepts and is equipped with layer techniques for activation/deactivation of layer contexts. This paper also presents a logical system for COP programs. This logic is necessary for the automation of testing, developing, and validating of partial correctness specifications for COP programs and is an extension of separation logic. A mathematical soundness proof for the logical system against the proposed operational semantics is presented in the paper.

1. Introduction

To support and dynamically control the modularization of crosscutting concerns [1], a new programming style, context-oriented programming (COP) [2], has appeared. COP can be defined as a programming approach that produces software that is dynamically adaptable. COP was invented to treat programming problems when the behavior of the required software changes at runtime depending on the execution conditions. This is not easily achieved by classical approaches of programming. COP was established on languages like Smalltalk [3], Java [4], and JavaScript [5]. While the idea of homogeneous crosscutting is to execute the same source code at the join points of concerns, the idea of heterogeneous crosscutting concerns is to execute different source code at the join points. Heterogeneous crosscutting [1] is the type of crosscutting concerns adopted by COP. Partial functions declarations adapting common functions to their new style are used in COP to implement these crosscutting methodologies.

Main components of COP include (a) layers of variant functions for providing performance alterations and (b) a tool for layer activation/deactavation. A variant function is a function that can be executed after, before, and around the same (variant) function included in another layer. Hence a layer is a group of variant functions.

Layer declarations are used to encapsulate partial function declarations. The semantics of classes and that of crosscutting can be combined at the runtime. COP [2] provides a block statement defining a group of layers to enable runtime layer composition. Determined by the statement block, an execution scope is also provided by COP. In this scope layers are typically combined with the base system. Another statement enables stopping execution of specified layers. The keywords denoting these two statements are with and without statements [2]. COP appears to be a very convenient technique for encapsulation of homogeneous crosscutting concerns as proved by many applications.

However, so far research did not provide appropriate logic to reason about context-oriented programs. A main concern in COP is the treatment of layers activations/deactivations. Usually, the set of active layers changes from one program point to another. Therefore the efficiency of any logic for COP strongly depends on using correct layers. In spite of the concept of activating/deactvating a layer is simple, and its logical treatment is a bit complex.

To reason about resources, Reynolds [6] and independently Samin and O’Hearn [7] presented new logic (separation logic). This was based on Burstall’s early work. A logical operator (separation conjunction) enabling localizing operation actions on shared resources is among the main contributions of separation logic. Sound form of local reasoning was reached by the separation conjunction which ensures the invariance of resources not included in preconditions.

To model the meanings of COP concepts, this paper introduces operational semantics. Accurate meanings for basics of COP languages are provided by the semantics. Axiomatic semantics for COP is the second contribution of this paper. This semantics is an extension of separation logic to establish and ensure partial correctness specifications for COP programs. Rather than other logic, separation logic seems most suitable for verifying COP. This is so as the concept of context changing is explicitly “treated” by the special operators of separation logic. One of the challenges in this paper is to expose this explicit relationship in the form of formal definitions and inference rules. Judgments of the proposed logic have the form meaning that(i)if layers of are active, then executing in a state satisfying is ensured not to abort,(ii)if layers of are active and the execution of in a state satisfying ended at some state, then this last state satisfies .

Assertions and may reason about the program control locations as well as upon the values of local and global variables. A system of axioms and inference rules constituting the proposed logic is introduced in the paper which presents a partial correctness specification, for example, COP-program, as well. Against the proposed operational semantics, the mathematical soundness of the logical system is shown in this paper.

Contributions of this paper are as follows:(1)new operational semantics to provide accurate meanings for COP concepts,(2)novel axiomatic semantics to construct and validate partial correctness specifications for COP programs.

The rest of the paper is organized as follows. Section 2 presents in detail the programming language J-COP and its operational semantics. The assertion language, axioms, and inferences rules constituting the logical system are presented in Section 3 which also presents the mathematical proof for the correctness of the system and an example of its use. Related research is presented in Section 4.

2. Programming Language and Operational Semantics

The syntax and semantics of the programming language (dubbed J-COP) used in this paper are presented in this section. Basic aspects of object-oriented programming like inheritance and subtyping are modeled in J-COP which follows Java syntax for comparable structures. Algorithm 1 presents the syntax of J-COP.

   
   
  
    
            
            
              
   
   
            
        

J-Cop is a rich model for COP. The model includes basic language constructs and is extendable directly over well-studied Java features. Although the model is expressive enough to include more language features, it is simple. In addition to typical Java constructs, the model allows layers activation/deactivation, overriding variant functions, and a technique for executing proceed and super.

We let denote the typical member of the set of names of classes which is included in the set of types (Types). In addition to , Types includes function and reference types. The typical element of Types is denoted by . As it is common in programming, J-COP’s functions contain local variables whose scopes are the same as their functions. Also parameters for functions are local variables which are denoted by LVar. Instance variables model internal states of classes. We let denote the set of instance variables of the class . The symbols and denote typical elements of LVar and , respectively. Sequences of layers activation/deactivation constitute layer expressions (LayerExpr) with . FunNames and LayerNames denote the sets of function and layer names, respectively, with and .

A class in J-COP includes function definitions and a group of layers containing function definitions. A function is defined via a parameter, a statement, and an expression. The expression models the returned value of the function. A set of classes and a main function (marks the start of program execution) are the components of a J-COP program.

The operational semantics of J-COP presented in this section is defined using state representations and a subtype relation on classes. If inherits by definition of , then is a subclass of (denoted by ) and is a superclass of . The reflexive transitive closure of is denoted by . States of the operational semantics are presented in Definition 1 where denotes an infinite set of memory addresses with and is the set of integers.

Definition 1. One has the following:(1);(2) and denote the sets of function and layer names of , respectively;(3);(4);(5);(6).

The set includes model values. States of the operational semantics are pairs of a stack and a heap. A special variable (called this), to point at the object being executed, is included in the set of local variables. For each class , we assume two functions and . The map determines for every function its components , the parameter variable of the function, the function statement, and the returned expression of the function. The map determines for every layer the parts of the layer’s function . We also assume a function SerLay whose inputs are a set of layers, a layer expression, and a function name. SerLay adds (removes) layers activated (deactivated) by to (from) . Then SerLay returns the set of layers in containing definitions for .

The semantics of arithmetic and boolean expressions of J-COP is similar to the case of simple imperative language. The cases of and are shown in Algorithm 2. Some comments on this algorithm are in order. The expression denotes the variable of the class referenced by . In line with common OOP concepts, variables of and that of its ancestors are included in domain of . Therefore the semantics of is defined only if is a local variable of the class referenced by or any of the class’s ancestors. The semantics of (in ) is supposed to be an address containing a class object. The semantics of is undefined if is the address of an object of a class that is not a descendant of .

Algorithm 3 presents the semantics of J-COP’s statements. The judgments of the semantics have the form meaning that executing in the state results in the state provided that is the set of the currently active layers. Some comments on the rules are as follows. The local variable of the object pointed to by is updated in the rule . This amounts to modifying the function in the image of under . With input , the rule provides semantics for running the function of the object pointed to by . The semantics of in is to activate/deactivate certain layers. The rule provides operational semantics for this statement. This rule does the call SerLay to add (remove) layers activated (deactivated) via to (from) . This call then returns the subset of with definitions for . The rule then executes the bodies of layer functions sequentially. The execution number builds on its previous execution by updating to the value . The statement running the function of an ancestor of the current object is given semantics in the rule . The rule assumes a function super that finds the ancestor of the class pointed to by such that this ancestor includes a definition for . Semantics for is given in the rule . This statement runs all functions in active layers of the object referenced by .

3. Assertion Language and Logical System

Extended separation logic to cover context-oriented programs is presented in this section. The section introduces the assertion language followed by the logical system’s axioms and inference rules. Against the operational semantics presented in the previous section, this section also outlines a formal mathematical proof for the correctness of the logical system. Finally an example of a derivation for a partial correctness specification using the logical system is included in this section as well.

Boolean expressions, classical connectives, first order quantifications, and assertions specific to separation logic are the components of separation logic assertions. The following version of assertions is used in this section.(i)emp denotes an empty heap.(ii) denotes that the heap has a unique memory cell whose address is and whose content is an instance of the class .(iii) denotes a special case of the previous assertion where .(iv) dubbed separating conjunction.(v) dubbed separating implication.(vi) is a general form of separating conjunction.

Algorithm 4 presents the specific definition of the language of assertions. A group of states are modeled by every assertion via a modeling relation (). The semantics of this relation is that the state satisfies the assertion . Definition 2 formalizes the semantics of the modeling relation.

     
     
           
             −*  .

Definition 2. One has the following:(i) for all . ;(ii);(iii) and ;(iv).  , and ;(v) for all .
The fact that is denoted by the expression . The union of heaps is denoted by and is defined only if .

A judgment of the proposed logical system is of the form where and are the pre- and postconditions, respectively. The semantics of this judgment is that if layers of are active and is executed in a state satisfying , then the final state will satisfy . Definition 3 formalizes the soundness concept of specifications produced by the logical system. Axioms and inference rules of the logical system are introduced in Algorithm 5.

We fix the abortion notion for Definition 3. A statement is aborting at (denoted by if (a) a state such that is not available and (b) is not stuck in an infinite loop.

Definition 3. A specification is sound if, for each such that , the following is satisfied:(1),(2)if , then .

Some of the rules in Algorithm 5 are certainly noteworthy. In many rules like and , the expressions of relevant statements contribute to the preconditions of the rules. This has the advantage of ensuring that the meant memory addresses are indeed allocated and hence evaluations of expressions do not abort. The preconditions of and also ensure that appropriate variables reference objects in heap. The side-conditions of and consider that executing these statements involves executing certain function bodies. We let denote the set of locations modified by provided that layers of are active. The symbol denotes the set of free variables of . The rule enables the composition of specifications having disjoint sets of activated layers if the preconditions of the specifications describe disjoint regions of the heap. The rule enables avoiding a frame of the heap, , that does not affect the statement. This rule also ensures that is satisfied by the postcondition.

Soundness. The soundness of the logical system is guaranteed by the following theorem.

Theorem 4. Specifications that resulted using the logical system of Algorithm 5 are sound (Definition 3).

Proof. Structure induction on axioms and inference rules of Algorithm 5 achieves the proof. In the following, basic cases are outlined.(i)The case of the rule : in this case(a), (b).Suppose that, for state . Hence and . Therefore is defined and so does . Hence . Now we suppose . In this case . Therefore because . This completes the proof for this case.(ii)The case of the rule : in this case(a), (b),(c),(d),(e).Suppose that, for state . This implies . The condition implies is defined. Therefore . By induction hypothesis does not abort at and therefore does not abort at . Now we suppose that . By , . Also by induction hypothesis implying . This completes the proof for this case.(iii)The case of the rule : in this case(a), (b), for all ,(c),(d)for all , this ,(e), (f)for all ,(g).Suppose that, for state . This implies . The condition implies is defined. Therefore . By induction hypothesis does not abort at . Now we suppose that . By induction hypothesis implying , this . Therefore by induction hypothesis does not abort at , this . Now we suppose that , this . By induction hypothesis implying , this . Therefore by induction hypothesis does not abort at , this . Hence a simple induction on completes the proof for this case.(iv)The case of the rule : in this case(a), (b), (c), (d), (e),(f).Suppose that, for state . This implies . The condition implies is defined. Therefore . By induction hypothesis does not abort at and therefore does not abort at . Now we suppose that . By , . Also by induction hypothesis implying . This completes the proof for this case.(v)The case of the rule : it is similar to the case of .

4. Discussion

Related Work. The most related logic to our work is that of object-oriented programs. Specifically for Java, a huge literature on specification proof techniques for object-oriented languages exists. For example, for annotated Java programs in JML (Java modeling language), [8] presents calculus for weakest precondition. An introduction to applications and tools of JML is presented in [9]. Via annotating Java source files, JML enables determining Java interfaces and classes. Considering abnormal termination resulting from failures of Java programs, [10] presents an extension to Hoare logic. For theses failures, transformational techniques do not work.

Notably, dynamically growing reference-structures are involved in object-oriented programs. This results in the aliasing problem in OOP languages. Much logic treating aliasing does exist. One of these techniques is presented in [11] and reasons about linked lists which are treated using separation logic [6]. Via including global stores in the assertion language, [12] presents Hoare logic for OOP languages. However the use of this model for global storing is proved to be a potential cause of incompleteness. Classes encapsulation in an OOP language equipped with subtyping and pointers is guaranteed by aliasing restrictions in [13].

The work in [14] is an example of logic achieving modular verification for OOP and focusing on corresponding methodology and object invariants. Modular verification of complex object structures was treated in [15] using an invariant class. Sound proof systems producing restricted formal justifications for OOP languages were introduced in [16, 17]. Producing a complete logical system for OOP languages is a very complex problem due to complex features of OOP languages.

Interestingly, none of the techniques mentioned above treat context-oriented programs. This adds to the value of the work presented in the current paper; apparently there is no research to generalize separation logic to cover context-oriented programs.

Operational semantics and type systems are presented in [18, 19] for checking and modeling context-oriented programs. The language model of [19] is structural and very similar to the model of the current paper. The language model of [18] is functional. Type systems introduced in both of these papers prevent execution of faculty functions by proceed. The operational semantics of the current paper is much simpler and powerful than semantics of [18, 19].

Utilizing concepts of delegation based calculus, [20] presents operational semantics for a COP language, namely, . For COP concepts as introduced in ContextJ* and ContextL, [21] introduces syntax-based semantics. Compared to the work mentioned above, a logical system that stops COP program from getting stuck is presented in the current paper. To model context-dependent behavior of COP programs, the proposed logical system is based on general calculi.

Future Work. Extending the language model of the current paper to allow executing candidate functions of proceed on priority bases is a direction for a future work. Extending the language to include layer inheritance and layer dependency is another direction for future work. Doing so allows one layer to assume the existence of another layer and allows expressing the assumption that two layers are not active at the same time.

Conflict of Interests

The author declares that there is no conflict of interests regarding the publication of this paper.