The role of linearity in sharing analysis

Abstract Sharing analysis is used to statically discover data structures which may overlap in object-oriented programs. Using the abstract interpretation framework, we show that sharing analysis greatly benefits from linearity information. A variable is linear in a program state when different field paths starting from it always reach different objects. We propose a graph-based abstract domain which can represent aliasing, linearity, and sharing information and define all the necessary abstract operators for the analysis of a Java-like language.


Introduction
In the context of static analysis of object-oriented programs, the aim of sharing analysis is to discover when two data structures may overlap. For instance, this may happen in Java programs, whose objects are stored in a shared memory called heap. Sharing information can be exploited in program parallelization and distribution, since methods working on data structures that do not overlap can be executed on different processors, using disjoint memory. Moreover, knowing sharing information is very useful for improving other kinds of analyses like shape, pointer, class, and cyclicity analysis.
Consider a class Tree with two fields l and r defined as follows: class Tree { Tree l; Tree r; } A concrete state in an object-oriented program is usually described by a frame, which is a map from program variables to memory locations (or null), and a memory, which is a map from locations to objects. Figure 1 shows two states with two variables x and y referring to two different objects of class Tree. In the state of Figure 1A, the variables x and y share, since x.r.r.r and y.l.l point to the same object. Traditionally, sharing analysis has been designed in two different ways: set-sharing analysis and pair-sharing analysis. In set-sharing analysis, we look for sets of variables which share a common object, while in pair-sharing analysis we are only interested in discovering pairs of variables which share. In this paper, we deal with field-sensitive pair-sharing properties.
We abstract concrete states into a new kind of graph we call Aliasing Linearity Pair Sharing (ALPS) graph. For instance, the state in Figure 1A is abstracted into the ALPS graph in Figure 1A where the dotted edges between two nodes encode the information that they share. All ALPS graphs have at most two levels. The first level consists of nodes which are labeled with program variables and may have both incoming and outgoing edges. Second level nodes are unlabeled, are connected by at least an incoming edge with first level nodes, and cannot have outgoing edges. Edges are labeled with field names. Dotted edges encode sharing information and can connect two nodes at any level.
As it is customary in the abstract interpretation theory Cousot 1977, 1992), the correspondence between ALPS graphs and concrete states is given by a concretization function that maps each graph to the set of all concrete states it abstracts. In this section, we try to describe the main feature of ALPS graphs while remaining at an informal level. Precise definitions will be given in the next sections.

Field-sensitive pair-sharing information
Sharing properties for logic programs has been studied extensively. The large literature on this topic and the paper by Secci and Spoto (2005a) on object-oriented programs have been the starting point for designing our abstract domain for sharing analysis.
We say that two locations share when it is possible to reach from them a common location. Consider the concrete state depicted in Figure 1A. Here x and y are bound to two different data structures which overlap, since x.r.r.r and y.l.l are bound to the same object: we say that x and y share. In the abstract graph, we represent this information with an (undirected) dotted edge between the two nodes. For instance, the sharing information in Figure 1A is captured by the four dotted edges in Figure 2A. In the following, in order to keep the graphs as simple as possible, we omit those dotted edges which can be inferred by other features of the graph. In this case, the only nonredundant edge is the one between x.r and y.l, as shown in Figure 2B. Note that our graphs encode possible pair-sharing information: the presence of a dotted edge means that the corresponding locations might share, while the absence of the dotted edge means that the corresponding locations do not share for sure. Therefore, the graphs in Figure 2 are correct abstractions also for the concrete state in Figure 1B, although x.r and y.l do not share in the latter.

Aliasing and nullness
ALPS graphs may encode definite nullness of variables and fields: a variable is null when it does not appear as a label, while a field v.f is null when there is no edge labeled with f departing from the node v. For example, in Figure 4 the field v 1 .r is null. Definite nullness means that when a node  is null in the graph, then it has to be null in the corresponding concrete states, but the converse is not true. For example, all the graphs in Figure 3 are correctly abstracted by Figure 4, since in all of them v 1 .r is null, although v 2 .r is null in some states ( Figure 3B and C) but not in others ( Figure 3A). The graph also encodes definite weak aliasing: two variables or fields are weakly aliased when they point to the same location or they point both to null. For instance, the variable v 1 and the field v 2 .l in the concrete state of Figure 3A are aliased, since they are bound to the same object. ALPS graphs encode aliasing information by using a single node for abstracting both variables/fields. For example, in Figure 4, the same node is labeled by both v 1 and the v 2 .l (more precisely, the node v 1 is reached by the edge labeled l departing from the node v 2 ). Note that, due to the definition of weak aliasing, v 1 and v 2 .l are considered to be aliased even in the concrete state of Figure 3C, hence Figure 3C is still correctly abstracted by Figure 4. Another example is in Figure 5.
We use the adjective weak to distinguish our treatment of aliasing by other proposals which consider two identifiers to be aliased only if they point to the same non-null location (see, e.g., Pollet et al. 2001).

Linearity information
In the field of logic programming, the use of a linearity property has proved to be very useful when dealing with sharing information (see Bagnara et al. 2005 for a comprehensive evaluation). We show how the same idea can be reused to enhance sharing analysis of object-oriented programs. We propose a new combined analysis of sharing, aliasing, and linearity properties for   Java-like programs based on abstract interpretation, inspired by the corresponding domains on logic programs. We say that a location is nonlinear when there are two different paths starting from it and reaching a common location. Consider for instance Figure 6. Starting from v 5 .r, we reach the same object by either v 5 .r.r.l.r or v 5 .r.r.r.l. Therefore, we say that v 5 .r is nonlinear. It is easy to note that also v 5 is nonlinear. In general, whenever a field v.f is nonlinear, the variable v is nonlinear too. We represent possible nonlinearity information by means of a double circle. For instance, the concrete state for variables v 5 and v 6 in Figure 6 is abstracted as in Figure 7.

An example program
Linearity plays a key role in sharing analysis, since it allows us to propagate precise sharing information when dealing with method calls. We show how the analysis works and the relevance of linearity information with the help of the example program in Figure 8.  We consider again the class Tree previously defined. The method makeTree defined in Figure 8 (left) builds a complete tree of depth n, whose nodes are all distinct. Actually, with a bottom-up static analysis using ALPS graphs, we can easily infer that, for any input n ≥ 2, makeTree returns a data structure which may be described by the graph in Figure 9A, where the label out denotes the return value of the method. Since there are no undirected dotted edges between out.l and out.r, it means that out.l and out.r do not share. Moreover, since there are no double circles, everything is guaranteed to be linear. The latter property implies that, in any concrete state approximated by the ALPS graph in Figure 9A, two different fields of the same object can never share. In particular, we know that out.l.l and out.l.r do not share.
The useTree method in Figure 8 (right) calls makeTree and extracts two subtrees which do not share. In detail, in the useTree method, since we know that t is linear, we can infer that tl is linear too. Since tl is linear, its fields tl.r and tl.l do not share, and therefore right and left do not share. Note that linearity of t is not needed to prove that t.l and t.r do not share (sharing is enough for this). We need linearity when we want to go deeper and prove that t.l.l and t.l.r do not share. Linearity of t is essential here in proving that left and right do not share. The heap at the end of the useTree method may be described by the graph in Figure 9B.
Due to the interaction between sharing and linearity, different ALPS graphs may represent the same set of concrete states. For example, adding a dotted edge between out.l and out.r in Figure 9A does not allow them to share, since that would violate the linearity of out. In Section 5, we will introduce a closure operator on graphs to deal with these interactions.

Plan of the paper
The rest of the paper is organized as follows. Section 2 summarizes the notations used through the paper and describes our simple Java-like language. Section 3 defines the basic notions of reachability, sharing, linearity, and aliasing. In Section 4, we introduce the domain of aliasing graphs, which encodes weak aliasing for variables and fields. Then, in Section 5 we enrich aliasing graphs with information regarding sharing and linearity, obtaining what we call ALPS graphs. Section 6 defines an abstract semantics (analysis) over ALPS graphs and states its correctness. Section 7 contains a discussion about related work and Section 8 concludes. Appendix A contains all the proofs of the properties and theorems in the paper. This paper is an extended and revised version of Amato et al. (2015). With respect to the conference version, this paper includes: (1) definitions for all the operators used in the abstract and concrete semantics; (2) the notion of graph morphism and closure; (3) all the proofs; and (4) many new examples.

Notations
We use a special notation for ordered pairs. The two components of an ordered pair are separated by . A definition of a pair s = a b silently defines the pair of selectors s.a and s.b.
A total (partial) function f from A to B is denoted by A → B (A B, respectively). Given f : A B and x ∈ A, we write f (x) = ⊥ when f is undefined on x. The composition of functions f and g is denoted by f • g. The domain and range of f are, respectively, dom (f ) and rng (f ). We denote by [v 1 → t 1 , . . . , v n → t n ] the function f such that dom (f ) = {v 1 , . . . , v n } and f (v i ) = t i for i = 1, . . . , n. We denote by f [w 1 → d 1 , . . . , w m → d m ] an update of f , with a possibly enlarged domain. By f | s (f | −s ), we denote the restriction of f to s ⊆ dom (f ) (to dom (f ) \ s, respectively).
Given a set X, we denote by P(X) the powerset of X and with P 2 (X) those subsets of X of cardinality 1 or 2. Given f : A B, Y ∈ P(B) and Z ⊆ P 2 (B), we denote by For an ordered set S ≤, if s ∈ S, then ↓ s = {s ∈ S | s ≤ s} is the downward closure of S. For a preordered set S ≤, we say that s 1 , s 2 ∈ S are equivalent, and we write s 1 ∼ s 2 , when s 1 ≤ s 2 and s 2 ≤ s 1 . The set S/∼ of equivalence classes modulo ∼ is ordered by [s 1 ] ≤ [s 2 ] iff s 1 ≤ s 2 . We will freely use preordered sets in the place where ordered sets are expected, implicitly referring to the induced ordered set.
We recall now the basics of abstract interpretation from Cousot (1977, 1992). Given two posets C ≤ and A (the concrete and the abstract domain), a Galois connection is a pair of monotonic maps α : C → A and γ : A → C such that γ • α is extensive and α • γ is reductive. It is a Galois insertion when α • γ is the identity map, that is, when the abstract domain does not contain useless elements. This is equivalent to α being onto, or γ one-to-one.
We say that a ∈ A is a correct approximation of c ∈ C when α(c) a or, equivalently, c ≤ γ (a). An abstract operator f A : A n → A is correct w.r.t. f : C n → C if, given a 1 , . . . , a n correct abstractions of c 1 , . . . , c n , we have that f A (a 1 , . . . , a n ) is a correct abstraction of f (c 1 , . . . , c n ). This is equivalent to f (γ (a 1 ), . . . , γ (a n )) ≤ γ (f A (a 1 , . . . , a n )) for every tuple a 1 , . . . , a n of abstract objects.
We use type environments to describe the identifiers in scope in a given program point. A type environment is a map from a finite set of identifiers to the associated class. The set of type environments is We call variables the identifiers in dom (τ ). Any class κ ∈ K defines a type environment, also denoted by κ, which maps the fields of κ (including both the fields defined in κ and those inherited by the superclasses) to their types.
We require that fields cannot be redefined in subclasses. It means that if f ∈ dom (κ) and κ ≤ κ, then f ∈ dom (κ ) and κ (f) = κ(f). For consistency of notation, we write κ.f in place of κ(f) for the type of the field f in the class κ.
Finally, we require the existence of a class with no fields which is the common ancestor of all other classes.
In the examples, we will describe the set of classes and the corresponding type environment using a notation inspired by class definitions in Java.
Example 1. Classes in the example program in Section 1.4 may be described by the following Java-like syntax: Expressions and commands are normalized versions of those in Java. Their syntax is the following: where κ ∈ K , f ∈ Ide and v, w, v 1 , . . . , v n ∈ Ide \ {res} are distinct when they appear in the same clause. Each method κ.m of a class κ is defined with a statement like κ 0 m(w 1 :κ 1 , . . . , w n :κ n ) with w n+1 :κ n+1 , . . . , w n+m :κ n+m is com where w 1 , . . . , w n , w n+1 , . . . , w n+m ∈ Ide are distinct and are not res nor this nor out. Their declared types are κ 1 , . . . , κ n , κ n+1 , . . . , κ n+m ∈ K , respectively. Variables w 1 , . . . , w n are the formal parameters of the method, and w n+1 , . . . , w n+m are its local variables. The method can also use a variable out of type κ 0 which holds its return value. We define body(κ.m) = com and returnType(κ.m) = κ 0 . Overriding methods cannot change the formal parameters but may specialize the return type. Given a type environment τ , with an abuse of notation we denote with τ (exp) the static type of an expression exp, defined as follows: Note that the static type of a field of class κ is recovered from the definition of κ, while the static type of the return value of a method call is the return type of the method.
We require expressions, commands, and methods to be well-typed, according to the standard definition in Java. We also require that all casts are explicit, so that in any assignment v := exp (resp. v.f := exp) the types of v (resp. v.f) and exp coincide. The same is required for formal and actual parameters. This is not a limitation since we allow upward and downward casts.

Semantics
The semantics of the language is defined by means of frames, objects, and memories defined as follows: where Loc is an infinite set of locations. A frame binds identifiers to locations or null. A memory binds such locations to objects, which contain a class tag and the frame for their fields. A new object of class κ is new(κ) = κ φ, with φ(v) = null for each v ∈ dom (κ).
and consider the state depicted in Figure 10, whose abstraction is in Figure 11. We have that Our language is strongly typed, which means that the static type of an expression should be consistent with its runtime type. We formalize here the notion of type correctness for a frame and a memory.
If v is a variable, the object associated with v should be of a subtype of the static type of v. This leads to the definition of weak correctness: Definition 4 (Weak τ -correctness). Let φ ∈ Frame τ and μ ∈ Memory. We say that φ μ is weakly We strengthen the correctness notion of Definition 4 by requiring that it also holds for the fields of the objects in memory.
Definition 5 (τ -correctness). Let φ ∈ Frame τ and μ ∈ Memory. We say that φ μ is τ -correct and write φ μ : τ , if (1) φ μ is weakly τ -correct and, We call state a pair φ μ which is τ -correct for some type environment τ . The set of τ -correct states is This may be depicted graphically as follows: It turns out that φ μ is weakly τ -correct, but it is not τ -correct, since the right child of u points to an integer node instead of a tree node.
The semantics of an expression is a partial map E I τ exp : τ τ +exp from an initial to a final state, containing a distinguished variable res holding the value of the expression, where Definition 7 (Semantics of expressions). Let τ describe the variables in scope and I be an interpretation. The semantics for expressions E I τ exp : τ τ +exp is defined as The semantics of a command is a partial map from an initial to a final state: C I τ com : τ τ . We assume that τ in both E I τ _ and C I τ _ does not contain the variable res.
Definition 8 (Semantics of commands). Let τ describe the variables in scope, I be an interpretation and The semantics for commands C I τ com : τ τ is defined as The identity function λσ ∈ τ .σ in the semantics of the sequence of commands is needed when p = 0.
Each method κ.m is denoted by a partial function from input to output states and an interpretation I maps methods to partial functions on states, such that I(κ.m) : input(κ.m) output(κ.m) , with the type environments: where w 1 , . . . , w n are fresh variables used to keep track of the actual parameters. Each w i is automatically assigned to the same value of the corresponding w i at the beginning of the method execution, and it is never changed later. The denotational semantics of a program is the least fixpoint of a transformer on interpretations which maps an interpretation I into a new interpretation I evaluating the bodies of the methods in I from an input state where local variables are bound to null. If κ.m is defined as

Reachability, Sharing, Linearity, and Aliasing
We formalize here the concepts of reachability, sharing, linearity, and aliasing for objects. In a later section, we will use these concepts to introduce the new abstract domain ALPS. The following definition will simplify notation later.
Every time we use these notations, we implicitly require that the conditions guaranteeing their existence are satisfied. The following proposition states very simple results relating types and states.
Note that, for any location l ∈ dom (μ), we have that l shares with itself.
Example 13. Consider the state σ = φ μ in Example 2. We have that l 0 and l 1 share in σ , since l 0 .r.r.r = l 1 .l.l.l = l 7 , while l 2 and l 4 do not share. Moreover, all the locations are linear.
If l.f = l it means that l is reachable from l. If we ignore the field f, we obtain the standard notion of reachability.
Definition 14 (Reachability relations). Given σ = φ μ ∈ τ and l, l ∈ dom (μ), we write An analogous characterization for linearity is not possible, since we need to discern among different ways of reaching the same location.
Using reachability, we refine our definition of interpretation, by requiring that a method does not access locations L of the input state which are not reachable from the actual parameters. Programming languages such as Java and that of Section 2.2 satisfy these constraints. This restriction will let us prove the correctness of method calls in the abstract semantics.
Definition 17 (Interpretation). An intepretation I maps methods to partial functions on state, that is, Note that the transformer of interpretations in Section 2.2.2 respects the conditions in Definition 17. Interpretations could be further restricted in such a way that if I(κ.m)(φ μ) = φ μ then rng (φ ) ∩ L = ∅. We do not enforce this condition since it is not necessary to prove correctness of the abstract semantics.

Reachability among identifiers
As we said before, we want to record sharing and linearity information not only for variables in the type environment but also for their fields. Therefore, we introduce some notation to treat variables and their fields as uniformly as possible.
Definition 18 (Qualified fields and identifiers). Given a type environment τ , we call qualified field an expression v.f where v ∈ dom (τ ) and f ∈ dom (τ (v)) and we call qualified identifier either a variable in dom (τ ) or a qualified field. We denote by Q τ and I τ the set of qualified fields and identifiers, respectively.
It is worth noting that we only consider fields that are in the declared type of the variables, and we do not consider further fields that are in the actual type. This choice, although it may decrease the precision of the analysis, simplifies a lot the correspondence between abstract and concrete semantics and may increase the speed of the analysis. Note that since dom (τ ) is finite, we have that I τ is also finite.
Example 19. In Example 2, the qualified fields are Q τ = {v 7 .l, v 7 .r, v 8 .l, v 8 .r} and the qualified identifiers are Definition 20 (Locations for qualified fields). If σ = φ μ ∈ τ and v.f ∈ Q τ , for uniformity of notation with variables we define The following proposition states that the runtime type of a qualified identifiers is a subtype of its declared type.
We now lift the definitions and properties of sharing and linearity from locations to identifiers.
Note that two identifiers that are both null are considered to be weakly aliased.
Example 23. In Figure 10, the field v 7 .r shares with v 8 .l. As a consequence, v 7 shares with v 8 .l and v 8 . The field v 7 .l shares only with itself and the parent. The identifiers v 7 and v 8 are linear, while v 5 , v 5 .r, and v 6 in Figure 6 are not linear.
Note that a qualified identifier i ∈ I τ shares with itself if and only if it is not null. Moreover, each i ∈ I τ such that φ(i) = null is linear and does not share with any other identifier.
Definition 24 (Reachability for qualified identifiers). Let σ = φ μ ∈ τ and i ∈ I τ . We define the set of locations reachable from i in σ as RLoc Note that the reachability set for a variable is related to the reachability set of its qualified fields. This is formalized by the following result.
Equality does not hold since there is some sharing information in RLoc σ (v) which is not derivable from the sharing information of its fields. This is due to the fact that we consider only fields in the declared type of a variables. Thus, further sharing relationships may exist in other fields which do not belong to the declared type.

Class-induced reachability
It must be observed that two qualified identifiers might never be able to share if their static types do not let them be bound to overlapping data structures. Analogously, certain qualified identifiers are forced to be linear.
Example 26. In Example 1, we have that a Tree is not an Integer, an Integer is not a Tree, and they do not have any field which can share. Therefore, any identifier of type Tree can never share with any identifier of type Integer. Moreover, any identifier of type Integer may only be linear.
Example 27. Consider the following classes: class B1 extends B { } Then, every object of class A is linear.
Identifying pair of classes which cannot share, or that are forced to be linear, may improve the result of the analysis. This is the topic of the rest of this section.
Definition 28 (Class reachability). We define a reachability relation between classes given by κ − → κ iff exists an identifier f such that κ ≤ κ.f. We denote by * − → the reflexive and transitive closure of − →.
In Definition 28, if a class κ (different from κ) is reachable from κ, then all its subclasses ↓ κ are considered reachable. This reflects the fact that we consider a language with (checked) casts. The following proposition relates reachability with class reachability: if location l 2 is reachable from l 1 , the type of l 2 should be reachable from the type of l 1 .
Proposition 29. Given σ = φ μ ∈ τ and l 1 , l 2 ∈ dom (μ), if l 1 * − → σ l 2 , then τ (l 1 ) * − → τ (l 2 ). This notion of class reachability corresponds to the one in Secci and Spoto (2005a) if we denote by C(κ) the set of classes reachable by ↓ κ, that is, We introduce this alternative notation since it will be convenient in the next definitions. We will denote by NL the set of classes whose instances may be nonlinear and by SH the set of pair of classes which may share. Both NL and SH may be computed using class reachability, that is, by typing information only.
First of all, note that identifiers i 1 and i 2 may share only if there is a common location l which is reachable both from φ(i 1 ) and φ(i 2 ). Therefore, the class τ (l) should be class reachable from both τ (φ(i 1 )) and τ (φ(i 2 )). This is formalized by the following: Definition 31 (The SH set). Given the type environment τ , we define the set of pairs of classes which may share: Proposition 32. Given i 1 , i 2 ∈ I τ , and σ ∈ τ , if i 1 and i 2 share in σ , then (τ (i 1 ), τ (i 2 )) ∈ SH.
We now consider the problem of linearity induced by type information. In general, an object of class κ may be nonlinear either if κ has two fields which may share, it has a field which may share with itself or if a nonlinear class κ is reachable from κ. This is formalized by the following: Definition 33 (The NL set). The set NL of nonlinear classes is the upward closure of the least solution of the equation: Note that NL is upward closed by definition. If κ is possibly nonlinear, the same holds for any κ ≥ κ since a variable of type κ may actually point to an object of class κ.
In the following sections, we use the concepts of sharing, linearity, and aliasing introduced before to define a new abstract domain, called ALPS (Aliasing Linearity Pair Sharing), for the analysis of Java-like programs.

Aliasing Graphs
We start by defining a basic domain encoding definite aliasing. The domain will also encode definite nullness, which is a useful and basic property of Java programs.
Definition 35 (Pre-aliasing graphs). A pre-aliasing graph over the type environment τ is a directed graph G = N E such that: • N is the finite set of nodes; • E ⊆ N × Ide × N is the set of directed edges, each labeled by an identifier; • : dom (τ ) N is a partial map from variables to nodes; with the additional condition that • ∀n ∈ N, ∀f ∈ Ide, there is at most an outgoing edge from n labeled by f and When it is clear from the context, we denote G.N, G.E, and G. just by N, E, and . Moreover, we denote G i .N, G i .E, and G i . by N i , E i , i , and similarly for other typographical variants of G.
Example 36. Consider three classes A, B, C where B extends A and has two fields f and g of class B. Figure 12A shows a pre-aliasing graph over τ .
We can extend from variables to qualified fields. Note that (v.f) only depends on (v) and not from v itself. Definition 37 (Extension of ). Given a pre-aliasing graph G = N E , we extend on qualified When it helps readability, we will annotate nodes in aliasing graphs both with variables and qualified fields. See, for example, Figure 12B. Moreover, in the examples we will denote a node n by any identifier i such that (i) = n.
The idea of a pre-aliasing graph is that, given an identifier i ∈ I τ , (i) = ⊥ means i is definitely null, while (i) = (j) means that i and j are either both null or aliased. Since we aim at designing a domain which encodes definite aliasing and nullness, we define a preorder on pre-aliasing graphs such that G 1 G 2 when G 1 has more aliasing and nullness information than G 2 .
Note that, given their intended meaning, some pre-aliasing graphs contain redundant information. For example, nodes which are not labeled by any qualified identifiers may be removed. On the converse, two identifiers i 1 , i 2 of incomparable types may be (weak) aliased only if they are both null. We therefore restrict our attention to the pre-aliasing graphs which present some additional regularity conditions. Definition 39 (Aliasing graph). An aliasing graph is a pre-aliasing graph G such that, for all n ∈ N, {τ (i) | i ∈ I τ ∧ (i) = n} is a nonempty chain. We denote by G τ the set of aliasing graphs over the type environment τ , by τ G (n) = {τ (i) | i ∈ I τ ∧ (i) = n} the type of the node n and by ψ G (n) = {τ (w) | w ∈ dom (τ ) ∧ (w) = n} for the type that may be inferred by variables only, with the proviso that the meet of an empty set of classes is .
Note that, although the type τ G (n) depends on all the qualified identifiers labeling that node, the edges possibly departing from the nodes depend on ψ G (n) only. We could have also adopted another approach for pre-aliasing graphs and allow edges n f − → m if f is a field in τ G (n). Although this could potentially improve precision, it comes at the cost of a greater complexity of several operations.
(a) (b) Figure 13. Comparison of aliasing graphs. We have explicitly annotated each node with its identity.
Example 40. The pre-aliasing graph in Figure 12A is not an aliasing graph due to the rightmost node b 2 c since τ (b 2 ) = B, τ (c) = C but {B, C} is not a chain. This means that the variables b 2 and c can never be aliased (and thus are both null).

Morphisms of aliasing graphs
We give in this section a different characterization of the preordering over aliasing graphs.

Definition 41 (Morphism of aliasing graphs). A morphism of aliasing graphs h
This notion of morphism respects the intended meaning of aliasing graphs. If h : G 1 → G 2 and 1 (v) = ⊥, then 2 (v) = ⊥. Moreover, if 1 (v) = 1 (w), then 2 (v) = 2 (w). Aliasing morphisms enjoys many interesting properties. In particular, Theorem 42. Given two aliasing graphs G 1 , G 2 , there exists a morphism from G 2 to G 1 if and only if G 1 G 2 . Moreover, the morphism, when it exists, is unique.
It is often easier to think in terms of morphism than to check whether Definition 38 holds: most of the proofs of the properties in this section use graph morphisms and the characterization in Theorem 42. Moreover, morphisms will be pivotal in Section 5 when comparing sharing and linearity information attached to different aliasing graphs.
Example 43. Let us consider the following classes: Consider the aliasing graphs G 1 and G 2 , respectively, in Figure 13A and B. There is a morphism h : By Theorem 42, we have that G 1 G 2 .

The lattice of aliasing graphs
We now show that for aliasing graphs has least upper bounds and greatest lower bounds, and we show how to build them. We begin by defining a new aliasing graph G 1 G 2 , which we will later prove to be the least upper bound. In the definition, we use the inverse function −1 . Note that −1 may be different if we consider as the map : dom (τ ) N in Definition 35 or as the map : I τ N in Definition 37. When it is not specified, the latter is assumed.
Example 45. Let us consider the same classes and type environment of Example 43. Figure 14 shows an example of lub of aliasing graphs. Note that, even without knowing the class definitions, the graphs contain enough information to justify the result of the operation. For example, in Figure 14A, the fact that the left child of the node ab does not contain b.l means that that l is not a field of τ (b), hence τ (a) is a subclass of τ (b).
An analogous, although more complex, definition may be given for G 1 G 2 , which we will later prove to be the greatest lower bound of aliasing graphs.
Moreover, let N be the largest subset of I τ / ∼ such that: We define the aliasing graph The definition above is similar to the one for : we start from defining an equivalence relation ∼ which propagates weak aliasing and we define G 1 G 2 whose nodes are equivalence classes of identifiers modulo ∼. However, propagation of nullness is more complex. There are several situations which may force an identifier to be null. • It may be that i 1 ∼ i 2 , but i 2 is null in either G 1 or G 2 . In this case, both i 1 and i 2 are forced to be null. This is the reason of the condition "[i] ∼ ⊆ −1 1 (N 1 ) ∩ −1 2 (N 2 )" in the first clause of the definition for N.
• Assume τ (i) = κ, τ (i 1 ) = κ 1 , and τ (i 2 ) = κ 2 , such that κ 1 ≤ κ, κ 2 ≤ κ with κ 1 and κ 2 incomparable. It may happen that 1 (i) = 1 (i 1 ) and 2 (i) = 2 (i 2 ), which implies i ∼ i 1 ∼ i 2 . However, this forces i, i 1 , and i 2 to be null, since there is no object which is both an element of κ 1 and κ 2 . This is cared by the condition "τ ([i] ∼ ) is a chain" in the first clause of the definition for N. • If variable v is forced to be null for one of the reasons above, then fields of v cannot exist. This is cared of by the second clause of the definition for N.
Example 47. Let us consider the following classes: Figure 15 shows an example of glb of aliasing graphs.
The following theorem proves that and are actually the least upper bound and greatest lower bound of aliasing graphs.

Projection
Several operations may be defined on aliasing graphs. Most of them will be introduced later, since they depend on the concrete semantics of our language. We introduce here only the operation of restriction of a graph to a subset of variables.
Definition 49 (Projection). Given a pre-aliasing graph G and a set of nodes X, we denote by G| X the tuple X E where It is immediate to check that G| X is a pre-aliasing graph. Given a pre-aliasing graph G = N E , a set of nodes X ⊆ N is said to be backward closed when, for each n ∈ X, if there exists n f − → n ∈ E, then n ∈ X. Given a set of nodes X, we denote by ← − X the smallest backward closed set of nodes containing X. Symmetrically, we define forward closed sets and the forward closure operator − → X . It turns out that if X is backward closed, then G| X G. Moreover, if G is an aliasing graph, G| X is too. More precisely, the following hold: Proposition 51. If G is a pre-aliasing graph and X ⊆ N is backward closed, then G| X G.
We will come back to this point when we introduce the abstract semantics.

The domain of aliasing graphs
Given a concrete state σ ∈ τ , we may abstract it into an aliasing graph which conveys the relevant information.
Definition 52. Given σ = φ μ ∈ τ , we define the abstraction of σ as an aliasing graph The abstraction of a state σ is essentially the representation of the environment and stores as an aliasing graph, limited to the locations reachable from a qualified identifier.
The following proposition shows that the abstraction of a concrete state is an aliasing graph.
The following propositions show that each aliasing graph can be viewed as the abstraction of a concrete state.
The map α a of Definition 52 may be lifted to the abstraction map of a Galois insertion from P( τ ) to G τ given by α a (S) = σ ∈S α a (σ ). The abstraction map induces the concretization map γ a : G τ → P( τ ), which maps aliasing graphs to the set of concrete states they represent. Its explicit definition, below, is straightforward:

Theorem 55. The preorder is the same preorder induced by γ a , that is, given G
The above theorem may be considered the analogous of injectivity of γ a when the abstract domain is preordered instead of partially ordered. It allows to prove that γ a (G 1 ) ⊆ γ a (G 2 ) by just checking G 1 G 2 .

ALPS Graphs
Aliasing graphs are a very concrete representation of the part of the program state which is reachable from variables through a single field access. Pair sharing and linearity, instead, summarize global properties of the state. We want to add possible pair sharing and possible nonlinearity information to an aliasing graph.
Definition 56 (Pre-ALPS graph). A pre-ALPS graph G = G sh nl is an aliasing graph G with a set sh ⊆ {{n, m} | n, m ∈ N} and a set nl ⊆ N.
When it is clear from the context, we denote G.G, G.sh, G.nl by G, sh, nl and The set sh in a pre-ALPS graph encodes possible pair sharing, while nl encodes possible nonlinearity. In particular, two identifiers i, j ∈ I τ may share when { (i), (j)} ∈ sh, while i may be nonlinear when (i) ∈ nl. This suggests to extend the preorder on aliasing graphs to ALPS graphs as follows: Proposition 57. Pre-ALPS graphs are preordered by the relation defined as: Not all the pre-ALPS graphs make sense, due to the way aliasing, nonlinearity, and sharing interact. In particular, some nonlinearity or sharing information is redundant, since it cannot happen in practice due to the class hierarchy under consideration: pairs {n, m} ∈ sh such that classes τ G (n) and τ G (m) cannot share, or variables n ∈ nl such that τ G (n) / ∈ NL. This is formalized by the following:

Definition 58 (Graph compatibility). Given an aliasing graph G
We define a reduction operation which takes pre-ALPS graph G and removes spurious sharing and linearity information.
Definition 59. (Reduced pre-ALPS graphs). Given a pre-ALPS graph G, let sh nl be the sharing and nonlinearity information contained in sh nl which is G-SH and G-NL, compatible, that is, Figure 16. Two pre-ALPS graphs with a loop and a concrete state which is in the concretization of the Pre-ALPS graphs G in Figure 16B.
We define the reduction of G to be the pre-ALPS graph red (G) = G sh nl and we say that a pre-ALPS graph G is reduced if red (G) = G.
Moreover, some sharing and nonlinearity information can be derived from other information. For example, if n is a node in G, then {n} should be in sh, otherwise any identifier i s.t. (i) = n is forced to be null and G could be simplified by removing the node n.
Definition 60. (Closed pre-ALPS graphs). We define a pre-ALPS graph G = G sh nl closed when it satisfies all the following properties: Point (1) is standard in sharing domains since each non-null variable shares with itself. Point (2) expresses the fact that any variable in a loop cannot be linear. Point (5) means that nl is backward closed, while Point (3) is obvious generalization of backward closure to sharing pairs. Finally, Point (4) formalizes the fact that if two different fields of an object o share, then o is not linear.
Example 61 (Pre-ALPS graphs with loops). Consider the concrete state in Figure 16A. Locations l 0 and l 1 are nonlinear, since l 0 .r.r = l 0 and l 1 .r.r = l 1 . This state is correctly abstracted by the pre-ALPS graph G in Figure 16B, where nodes a and b are marked as nonlinear. On the contrary, the same concrete state is not correctly approximated by the pre-ALPS graph G in Figure 16C, since the latter does not allow for the nonlinearity of a and b. Actually, the only concrete states which are correctly abstracted by G are the ones where both a and b are null, since every other situation would violate either the aliasing constraints (a.r = b and b.r = a) or the linearity constraint. The Pre-ALPS graph G is closed according to Definition 60, while G is not and it is essentially not used, since it may be replaced by the empty pre-ALPS graph.
We want to restrict our attention only to those pre-ALPS graphs which do not contain any spurious information and where all sharing and nonlinearity information is explicit.
Definition 62 (ALPS graph). An ALPS graph G is a pre-ALPS graph which is reduced and closed. We denote by ALPS τ the set of ALPS graphs over the type environment τ .

Projection
Analogously to aliasing graphs, we define a projection operator for ALPS graphs.
Definition 63 (Projection of pre-ALPS graphs). Given a pre-ALPS graph G and X ⊆ N backward closed, we denote by G| X the pre-ALPS graph G| X sh nl where In the definition above, the hypothesis that X is backward closed is needed in order to ensure that G| X is an aliasing graph and not just a pre-aliasing graph. It is immediate to check that projection maps ALPS graphs to ALPS graphs. More specifically: Moreover, the following holds: Proposition 65. If G is a pre-ALPS graph and X ⊆ N is backward closed, then G| X G.

Up-and down-closures of pre-ALPS graphs
Given a pre-ALPS graph G, the up-closure of G is a new pre-ALPS graph, obtained by adding derived sharing and nonlinearity information to the sh and nl components. Moreover, if G is reduced (i.e., it does not contain spurious sharing and nonlinearity elements which are not G-SH-compatible and G-NL-compatible, respectively), then the up-closure of G is an ALPS graph.
Definition 66. (Up-closure of pre-ALPS graphs). Given a pre-ALPS graph G = G sh nl, we define the up-closure of G as the pre-ALPS graph cl ↑ (G) = G sh nl such that sh nl is the smallest pair, under the component-wise ordering, which contains sh nl and G sh nl is closed.
It is immediate to see that the up-closure of a pre-ALPS graph G always exists and can be simply computed starting from sh nl and adding new elements according to the five properties in Definition 60. Note that the graph G does not change when computing the up-closure.
Symmetrically, we can define the down-closure as follows.
Definition 67. (Down-closure of pre-ALPS graphs). Given a pre-ALPS graph G, we define the down-closure of G as the pre-ALPS graph cl ↓ (G) such that cl ↓ (G) is the greatest pre-ALPS graph smaller than or equal to G and such that cl ↓ (G) is closed.
Note that, differently from the up-closure, when computing the down-closure the graph G can possibly change, since some nodes could be removed. The next proposition shows how to compute the down-closure.
Theorem 68. Given a pre-ALPS graph G = G sh nl, the down-closure cl ↓ (G) can be computed as follows. Let sh * nl * be the greatest pair, under the component-wise ordering, such that Then, we have that The down-closure shows the interaction between the three components of aliasing (which is encoded in the graph structure), sharing, and nonlinearity. It precisely describes how linearity and sharing information propagate to the other components.
The first point states that whenever a node m is linear, then all its children are linear too. The second point explains the interaction between sharing and linearity: when a node n is linear, then its children cannot share. Moreover, when a node n does not share with a node m, the same holds for the children of n . Note that, whenever in a loop of the graph a node is linear, then all the nodes in the loop and all their children must be null. This is reflected in the projection on N \ − → X .
Example 69. Figure 17 shows the aliasing graph G and the ALPS graph G = G sh nl where In Figure 17B, nonlinearity is represented with a double circle, while sharing information is represented as follows: • the sharing information of the singletons {ab}, {c}, {a.r c.l}, {c.r} can be deduced from the existence of the nodes in the aliasing graph; • the sharing information of a node with its field, for example, {c, c.r}, can be deduced from the corresponding edge in the aliasing graph c r − → c.r; • additional sharing information is represented with a dotted line, for example, between the nodes ab and c.

The lattice of ALPS graphs
In order to define an abstract domain of ALPS graphs, we start by defining the least upper bound G 1 G 2 and greatest lower bound G 1 G 2 of ALPS graphs. We use morphisms when we need to combine sharing and nonlinearity information coming from different graphs with different sets of nodes. Definition 70. Let G 1 and G 2 be ALPS graphs. We define G = G 1 G 2 as: Example 71. Consider the ALPS graphs in Figure 18A and B. For ease of notation, we assume a node to be denoted by its label. The morphisms h 1 : G 1 G 2 → G 1 and h 2 : G 1 G 2 → G 2 are defined as follows: We have that: Example 73. Consider the ALPS graphs in Figure 19A and B. For ease of notation, we assume a node to be denoted by its label. The morphisms h 1 : G 1 → G 1 G 2 and h 2 : G 2 → G 1 G 2 are defined as follows: Figure 19. Greatest lower bound of ALPS graphs.
With an abuse of language, we denote the top and bottom of ALPS graphs for the domain environment τ with τ and ⊥ τ , which are the same symbols used for aliasing graphs. We omit the index τ when it is clear from or not relevant in the context.

The domain of ALPS graphs
Given a concrete state σ ∈ τ , we may abstract it into an aliasing graph which conveys the relevant information.
Definition 75 (Abstraction map on ALPS graph). Given σ ∈ τ , we define the abstraction α : The abstraction of a state σ is essentially the representation of the environment and stores as an ALPS graph, limited to the locations reachable from a qualified identifier. Given nl. Hence, G actually encodes possible sharing and nonlinearity among variables and fields.
Proposition 76. (Concretization of ALPS graphs). The concretization map induced by the abstraction map α satisfies the following property: Note that ALPS-graphs do not form a Galois insertion with concrete states, as shown in the following example.
Example 77 (ALPS-graphs do not form a Galois insertion). Consider the following set of classes: Since all classes may share among them, we have SH = {(κ, κ ) | κ, κ ∈ {A, B, C}}. Let τ be the type environment τ = {x → A, y → B} and consider the ALPS-graph G given by: x y It turns out that there is no set of states S such that α(S) = G. This is because, due to the set of classes we have available, x and y may only share through the class C, that is, through the fields f and g. But according to G, f and g should be null, making sharing impossible. Therefore, α is not surjective and α, γ is a Galois connection but not a Galois insertion.
Obtaining a Galois insertion would require the addition of new closure conditions on ALPS graphs. This is possible, but would make the definitions more cumbersome, and we have decided not to follow this line. While Galois insertions are more theoretical appealing since they do not contain redundant abstract elements, precise and efficient analysis can be obtained even without them. In the literature of numerical abstract domains (Amato and Scozzari 2012;Cousot and Cousot 1976) there are many examples of analysis which do not form a Galois insertion and not even a Galois connection, such as the polyhedral analysis of imperative programs (Cousot and Halbwachs 1978) and the parallelotope abstract domain (Amato et al. 2017), which nonetheless enjoy interesting completeness properties (Amato and Scozzari 2011) In the next section, we will define the necessary operations on the domain of ALPS graphs in order to define an abstract semantics for sharing analysis. Note that, since the abstract domain is finite, we do not need a widening operator to ensure the termination of the analysis.

An Abstract Semantics on ALPS
We present the abstract semantics on the domain ALPS τ . We provide a correct abstract counterpart for each concrete operator in the standard semantics. The abstract counterpart of an interpretation is an ALPS interpretation, defined as follows.
Definition 78. An ALPS interpretation I maps methods to total functions such that I(κ.m) : ALPS input(κ.m) → ALPS output(κ.m) for each method κ.m.

Auxiliary operators
First of all, we introduce some auxiliary operators which will be used later in the abstract semantics for commands and expressions.

Pruning
Given a triple G = G sh nl (not necessarily an ALPS graph), the operation prune removes extraneous nodes and adds inferred information:

Restriction
Consider the operation on concrete states which, given S ⊆ τ and a set of variables V ⊆ dom (τ ), returns the set of states in S restricted to the variables in V, that is, Starting from a correct abstraction G ∈ ALPS τ of the set of states S, we would like to define a new abstraction G ∈ ALPS τ | V which correctly approximates S V .
Definition 79 (Abstract restriction). Given G ∈ ALPS τ and V ⊆ dom (τ ), we define sh nl . Since is obtained by restricting to the variables in V, we have that for any x ∈ dom (τ ) \ V, (x) = | V (x) = ⊥. Then for each n ∈ N , −1 (n) ⊆ W and all the nodes in G which are not the image of a qualified identifier in W are removed from the graph. By construction and since G ∈ ALPS τ , we have that N is backward closed and G V ∈ ALPS τ | V .

Nullness propagation
Consider the operation on concrete states which, given S ⊆ τ and an identifier i ∈ I τ , returns the subset of those states in S where i is null, that is, If G is a correct abstraction of S, it is also a correct abstraction of S |i=null , but we would like to refine G into a more precise abstract state which still correctly approximates S |i=null . This suggests the following definition.
Definition 81 (Abstract nullness propagation). Given G ∈ ALPS τ and an identifier i ∈ I τ , we define In G |i=null , since the identifier i is forced to be null, all the nodes reachable from i need to be removed from the graph since they do not really exist. Given that N \ −−→ { (i)} is backward closed, we know from Propositions 64 and 65 that G |i=null is an ALPS graph and G |i=null G.
Nullness propagation is a special case of greatest lower bound between ALPS graphs, as proved in the following: Proposition 82. For each G ∈ ALPS τ and i ∈ I τ , G |i=null = G |i=null .
In turn, this allows us to prove that: In the rest of the paper, given i, j ∈ I τ , we use G |i=null,j=null as a short form for (G |i=null ) |j=null .

Restriction to aliasing
Consider the operation on concrete states which, given S ⊆ τ and two variables v, w, returns the subset of those states in S where v is weakly aliased with w, that is, Similarly to what we have done in the previous section, we aim to determine a correct approximation of S |v=w . Given G ∈ ALPS τ , we define In the rest of the paper, we will use G |v 1 =w 1 ,...,w n =w n as a shorthand for ((G |v 1 =w 1 ) . . . ) |v n =w n .

Abstract semantics for expressions
The abstract semantics specifies how each expression exp transforms input abstract states G = N E sh nl into final abstract states G = N E sh nl where res holds the exp's value. Abstract semantics for expressions (and later commands) is given compositionally on their syntax.  We briefly explain the behavior of the abstract semantic operators with respect to the corresponding concrete ones. The concrete semantics of null κ stores null in the variable res. Therefore, in the abstract semantics, we only need to add the new variable res into the type environment, without modifying the abstract state.
The concrete semantics of new κ stores in res a reference to a new object o, whose fields are null. The other variables do not change. Since o is only reachable from res, variable res shares with itself only and is clearly linear. Therefore, we only need to add a new node labeled with res and the corresponding sharing singleton, without affecting nonlinearity information.
The concrete semantics of v simply makes res an alias for v. Since the types of v and res coincide, we only need to add the variable v to the same node of res. The other variables are unchanged.
When v = null, then (κ)v behaves like null κ. If κ and the type of v are not compatible, then (κ)v only returns a nonfailed state when v = null. Therefore, in the abstract semantics, (κ)v restricts the input graph G to those states where v = null. In the other cases, the cast (κ)v stores in res the value of v. We use an auxiliary operator add (G, n, κ), explained in the following section, which adds the label res to the node n, and possibly adds new nodes for the fields of res which are not fields of ψ G (n). In this case, we can exploit the notion of linearity. In fact, when v is linear, we know that fields of res cannot share with each other and are linear.
The concrete semantics of v.f stores in res the value of the field f of v, provided v is not null.
When v.f is not null, this essentially amounts to the same procedure of the previous case.

Assignment to a node
The auxiliary operator add(G, n, κ) adds a new variable res of type κ as an alias of the node n ∈ N. The operator also adds children of res when needed to have an ALPS graph.
, κ} is not a chain cl ↑ (G ) otherwise Given G = G sh nl, in order to define G , let κ = ψ G (n) be the inferred type for node n in G (from variables only) and F = dom (κ) \ dom (κ ) = {f 1 , . . . , f m } be the set of the new fields in class κ which are not currently considered in G; let also {n f 1 , . . . , n f m } be a set of fresh nodes, that is, such that {n f 1 , . . . , n f m } ∩ N = ∅; then: Definition of G is straightforward: we just add the new nodes as children of node n, each one pointed through the corresponding field in F . If n is nonlinear, then all new nodes are nonlinear, all new nodes share among them and with other nodes n sharing with n. This procedure might add spurious sharing or nonlinearity information: we solve this problem by filtering with SH and NL.
When n is linear, then all new nodes are linear, do not share among them, and do not share with any node n reachable from n through a nonempty sequence of fields f 1 , . . . , f k in E, but share with all the other nodes sharing with n.

Abstract semantics for commands
In the concrete semantics, each command com transforms an initial state into a final state. On the abstract domain, it transforms an initial ALPS graph G sh nl into an ALPS graph G sh nl .
Definition 86. Let τ describe the variables in scope and I be an ALPS interpretation. Figures 21-23 show the ALPS semantics for commands S C I τ com : ALPS τ → ALPS τ .
The concrete semantics of v := exp evaluates exp and stores its result into v. Thus, the final abstract state is obtained by first computing SE I τ exp and then renaming res into v. Some of the nodes may become unlabeled and must be removed. This is accomplished by the auxiliary operation prune which removes unnecessary information, in particular unlabeled nodes and fields which are not in the declared type of the variables. To determine a correct approximation of the conditional "if v = null" we check whether (v) = ⊥. If this is the case, then we know that v is null and we evaluate com 1 . Otherwise, we evaluate both branches and compute the lub. When evaluating the first branch, we may improve precision by using the auxiliary operator G |v=null (Section 6.1.3) which returns a correct approximation of the program states {φ μ | α(φ μ) G ∧ φ(v) = null}, that is, the states correctly approximated by G where v is null. Note that, since our domain does not model definite nonnullness, there is no way to define a projection G |v =null to improve the input for S C I τ com 2 as in S C I τ com 1 (G |v=null ). Similarly for the conditional "if v = w" where we use another auxiliary operator G |v=w (Section 6.1.4) which returns a correct approximation of the set of program states Again, since our domain does not model definite not aliasing, we cannot improve the input for the second branch.
The composition of commands is denoted by functional composition over ALPS, where the identity map λs ∈ ALPS τ .s is needed when p = 0. The evaluation of v.f := exp in Figure 22 is the most complex operation of the abstract semantics. Although it may seem similar to the assignment v := exp, we must take into account that v might be aliased to many different nodes. The candidates are those variables, denoted by V comp , which share with (v) and have compatible types. For each node labeled by a variable in V comp , we add a new fresh node in N new pointed by an edge (labeled by the field f) in E new . Finally, all possible sharing and nonlinearity are added. A slightly different treatment is devoted to the special case when the result of the expression is definitely null.

Abstract semantics of method call
The concrete semantics of the method call v.m(v 1 , . . . , v n ) builds an input state containing the local variables w 1 , . . . , w n and the special variable this, and executes the method body. In order to improve the precision of methods call, we also use a copy of the local variables w 1 , . . . , w n which will be used when returning from the method call to match the original variables v 1 , . . . , v n . This allows a change to the object pointed by w i to be distinguished from a change to w i itself.
When a method v.m is called, the class of v is inspected and the correct overloaded method for m is selected. The abstract domain contains only a partial information on the runtime class of v, since we only know that the class of v must be a superclass of the class of any variable aliased with v, namely a superclass of τ G ( (v)). We exploit this information in computing the abstract semantics of a method call in Figure 23. In practice, we conservatively assume that every method m in any subclass of τ G ( (v)) may be called. Note that methods defined only in superclasses of κ are already considered in κ.
When exiting from a method call, we need to rename out into res since, from the point of view of the caller, the returned value of the callee (out) is the value of the method call expression (res). We use an auxiliary operation match v.m which, given an initial and final state, updates the initial state trying to guess a possible matching of variables in the abstract states. The definition of match v.m is given in Figure 24. Analougously to the concrete case, we may define an abstract transformer which, given a ALPS interpretation I, returns a new ALPS interpretation I such that The new interpretation returned by the abstract transformer is computed by first adding primed variables which are used to hold a copy of the original actual parameters, then evaluating the body of the method and finally restricting the graph to the output variables. The abstract denotational semantics is the least fixpoint of this transformer.
We can compute a new ALPS interpretation from the least informative ALPS interpretation I ⊥ (Tree.makeTree) = λG.⊥ out(Tree.makeTree) : Now, starting from I 1 (Tree.makeTree), we can compute a new interpretation as follows: which is the least fixpoint. Relatively to the case (n) = null, the abstract states I 1 (Tree.makeTree)(G) and I 2 (Tree.makeTree)(G) are depicted in Figure 25. From this graph, it appears that the tree generated by this method is linear and does not share with this (the object on which we call the makeTree method). Moreover since n and n are aliased we know that the method does not modify the variable n.

Related Work
Sharing properties has been deeply studied for logic programs, see for instance: Jacobs and Langen (1992), Hans and Winkler (1992), Muthukumar and Hermenegildo (1992), Codish et al. (1999), Bagnara et al. (2002), and Amato and Scozzari (2009). The large literature on this topic has been the starting point for designing our enhanced abstract domain for sharing analysis. In particular, the use of a linearity property, for example, Codish et al. (1991), Hans and Winkler (1992), Muthukumar and Hermenegildo (1992), King (1994), and Scozzari (2010, 2014), has proved to be very useful when dealing with sharing information (see Bagnara et al. 2005 for a comparative evaluation). Outside of the logic programming community, sharing information is generally regarded as a by-product of shape analysis. One of the first papers that explicitly deals with sharing information is Jones and Muchnick (1979), which presents a combined intra-procedural analysis of aliasing, reachability, and cyclicity for imperative and functional languages with records. The focus of their analysis is not pair sharing, but detecting the set of shared nodes, that is, heap cells which may be reached by variables using at least two different paths. Shared nodes and cyclicity are used to optimize memory management.
The property of sharing for object-oriented languages has been studied in a few works. Secci and Spoto (2005a) propose a simple domain of pair sharing for a simple Java-like language and Méndez-Lojo and Hermenegildo (2008) extend this domain proposing a combined analysis of set sharing, nullness, and classes for exactly the same language. The main differences of our paper w.r.t. these proposals are • the ALPS abstract domain encodes linearity and aliasing information, in addition to sharing; • the analysis is field sensitive, that is, information is encoded at the level of the fields of the objects.
The analysis in Secci and Spoto (2005a) has also been refined by Zanardini (2018) which proposes a field-sensitive sharing analysis for a very similar language. Linearity information is not exploited in this paper either. Pollet et al. (2001) propose a framework for the analysis of object-oriented languages and introduce two abstract domains for definite aliasing and possible aliasing, respectively. The abstract objects of these domains are similar to aliasing graphs, but without being restricted to two levels. Termination is guaranteed by widening. These domains may be enriched by providing type information for the leaves of the graphs. However, they do not consider sharing or linearity properties.
In the context of pure functional programming with no destructive updates, sharing is just an implementation detail and has not impact on the behavior of the program. Nonetheless, sharing analysis may help in optimizing program execution. For example, the first part of Jones and Muchnick (1979) deals with sharing in pure functional programs in order to avoid the use of garbage collection and reference counting.
More recently, Peña-Marí et al. (2006) present a pair-sharing analysis for SAFE, which is a functional language with explicit control for copy and destruction of data structures. The result of the analysis is used during type checking. Due to the particular features of the programming language, the sharing analysis distinguishes between generic sharing and sharing of recursive substructures (e.g., two lists share a recursive substructure when they have a common tail). The analysis is field insensitive and cannot represent neither definite aliasing nor definite nullness and linearity. This analysis has been vastly improved in Montenegro et al. (2015), where each pair of sharing variables is annotated with the set of possible paths through which the sharing may happen. Although definite aliasing and definite nullness are still not representable in the new domain, definite linearity is inferable by the extended pair-sharing information: if x shares with itself only through the empty path, then x is linear.

Conclusions
We propose the new abstract domain ALPS which combines aliasing, linearity, and sharing analysis for an object-oriented language and provide all the necessary abstract operations.
The combination with linearity information allows us to improve the precision of the analysis in blocks of assignments, method calls, and thus on recursion. This is a fundamental issue that has not been considered in any previous analysis. We have shown in Section 1.4 a simple example where linearity plays a fundamental role in proving that two subtrees do not share. More generally, an important point is that linearity information allows us to distinguish a tree from a direct acyclic graph (DAG). For instance, the result of makeTree in Figure 8 is a tree. However, the abstract representation of a tree in any abstract domain containing only information about reachability, sharing, acyclicity, nullness, and aliasing (and the corresponding negated properties such as cyclicity, non-nullness, etc.) cannot be distinguished from the abstraction of a DAG. For example, the data structure t2: Tree t2 = new Tree () t2 .l = new Tree () t2 .r = new Tree () t2 .l.l = new Tree () t2 .l.r = t2 .l.l has the same sharing, acyclicity, nullness, etc. properties of a tree, but t2 is not linear, while t in Figure 8 is linear. At the end of the method useTree, left is equal to t.l.l, right is t.l.r, but they do not share since t is a tree. However, t2.l.l and t2.l.r share. Linearity allows to distinguish these two situations. None of the works discussed in Section 7 can distinguish a DAG from a tree, with the exception of Montenegro et al. (2015) which cannot be directly applied to a Java-like language since it does not support updates.
Regarding modularity of the analysis, although the most precise results are obtained by analyzing the entire program as a whole, it is possible to analyze single libraries (or even single methods) by assuming the every external method returns the largest possible abstract object. In this way, when a real object will we plugged in the final program, its behavior will be correctly abstracted.
From the point of view of performance, note that in a domain which tracks possible sharing information, it usually happens that the more precise an abstract object is, the smaller its representation is. For example, the best correct abstraction of a concrete state where no sharing happens is an ALPS graph without edges. However, if our analysis is not precise enough to compute the best correct abstraction, some edges will be included in the abstract object, which may negatively impact the performance of succeeding operations. Therefore, improving the precision of the analysis, from the one side, increases the computational cost, but from the other side may lead to smaller abstract objects which partially compensates this cost. A detailed evaluation of the tradeoff between precision and performance may only be conducted experimentally. We plan to carry on this evaluation once we implement ALPS as an abstract domain for the Jandom static analyzer (Amato et al. 2013).
Although we have presented ALPS graphs in the context of object-oriented programs, the same domain can be immediately applied to functional programs. In this regard, note that the example program in Figure 8 may be rewritten in functional style and the benefits of linearity are the same already discussed for object-oriented programs.
The domain of ALPS graphs may be easily extended by annotating nodes with additional information in a modular way. For example, class analysis might be integrated by adding a set of possible classes for each node, while nodes representing numerical entities may be annotated with intervals for integrating range analysis. Obviously, if we want to maximize the benefits of the integration, at the very least, new operators should be devised which use the information of one domain to improve the precision of the other.
To the best of our knowledge, this is the first attempt to combine sharing with linearity for imperative or object-oriented languages.
We now prove the second property. Since l.f exists, then l exists and μ(l) ∈ rng (μ). By this reason and τ -correctness of σ , we have that μ(l).φ μ is weakly μ(l).κ-correct. If we consider what this means for the identifier f, and since l.f = μ(l).φ(f) = null by hypothesis, we have that
The operator C for class reachability is downward closed and monotone w.r.t. subtyping.
Proof. The first property immediately descends from the fact that C(κ) = κ ≤κ {κ | κ * − → κ } is the union of downward closed sets. The second property is an immediate consequence of the definition of C.
This concludes the proof.

A.2 Aliasing graphs and aliasing morphisms
The following proposition relates edges in aliasing graphs with reachability among classes.
Proposition 95. Given an aliasing graph G and nodes n, m ∈ N, we have that: Since fields cannot be redefined in subclasses, τ (v).f = ψ G (n).f, hence the thesis. The second point is an immediate corollary.
In the following, we show that (v.f) only depends on (v) and not on v itself.
Proposition 97. Given two aliasing graphs G 1 , G 2 ∈ G τ , the following properties are true for every h : G 1 → G 2 : • h is the unique morphism from G 1 to G 2 ; • h is surjective; • h is an isomorphism iff it is total and injective; the inverse morphism is h −1 .
Proof. For the first point, assume h : G 1 → G 2 . Then, for each node n ∈ N 1 , there is an identifier i ∈ I τ such that 1 (i) = n. Therefore, h (n) = h ( 1 (i)) = 2 (i) = h( 1 (i)) = h(n), that is, h = h . For the second point, given n ∈ N 2 , there is i ∈ I τ such that n = 2 (i). Since 2 (i) = h( 1 (i)), then n is in the range of h, hence h is surjective. The third point is straightforward.
Finally, it is possible to characterize the preorder between aliasing graphs without using the concept of morphism of graphs.
Theorem 42. Given two aliasing graphs G 1 , G 2 , there exists a morphism from G 2 to G 1 if and only if G 1 G 2 . Moreover, the morphism, when it exists, is unique.
Proof. The proof is straightforward by Proposition 97 and Theorem 99.

A.2.1 The lattice of aliasing graphs
First of all, we prove a characterization for least upper bounds.
Lemma 100. Assume given G 1 , G 2 , G ∈ G τ such that G 1 G, G 2 G, with morphisms h 1 : G → G 1 and h 2 : G → G 2 . Then, G is the least upper bound of G 1 and G 2 if: Proof. First of all, observe that the existence of h 1 and h 2 follows by Theorem 99. Moreover, note that the two conditions are equivalent to ∀n, m ∈ N ∪ {⊥}. (h 1 (n) = h 1 (m) ∧ h 2 (n) = h 2 (m)) ⇒ n = m. If the original condition holds and there are n, m ∈ N ∪ {⊥} with h 1 (n) = h 1 (m) ∧ h 2 (n) = h 2 (m), we have that: either n, m ∈ N, and the results follow immediately, or one among n and m is ⊥. Assume without loss of generality that n = ⊥. Then h 1 (m) = h 2 (m) = ⊥ which implies m = ⊥ by hypothesis, hence n = m. On the converse, if the condition stated above holds and h 1 (n) = h 2 (n) = ⊥, then h 1 (n) = h 1 (⊥) and h 2 (n) = h 2 (⊥), hence n = ⊥. Now, assume this property hold, and we prove that G is the least upper bound. Let G such that G 1 G and G 2 G with corresponding morphisms h 1 and h 2 . We need to build a morphism h : G → G. For each n ∈ N , consider a qualified identifier i ∈ I τ such that (i) = n and we define h(n) = (i). We prove that h is well defined and that it is a morphism. Assume there are i , i with i = i, (i) = (i ) = n. Then 1 (i) = 1 (i ) and 2 (i) = 2 (i ), that is, h 1 ( (i)) = h 1 ( (i )) and h 2 ( (i)) = h 2 ( (i )). By the alternative formulation of hypothesis, this implies (i) = (i ). Therefore, h is well defined. Now, we prove (i) = h( (i)) for each i ∈ I τ . If (i) ∈ N , this is immediate, since h( (i)) is (i ) for some identifier i such that (i ) = (i). Obviously i = i is a good choice, hence (i) = h( (i)). If (i) = ⊥, then 1 (i) = 2 (i) = ⊥ hence h 1 ( (i)) = h 2 ( (i)) = ⊥. By hypothesis, (i) = ⊥ = h( (i)).
Then, using this characterization, we prove that G 1 G 2 in Definition 44 is the least upper bound of G 1 and G 2 .
Theorem 101. The aliasing graph G 1 G 2 is the least upper bound of G 1 and G 2 .
Proof. G is a pre-aliasing graph). First of all, we prove that G = G 1 G 2 is a pre-aliasing graph.
Given S 1 ∈ N and f ∈ Ide, assume that there are S 2 , S 2 in N such that S 1 f − → S 2 and S 1 f − → S 2 . This means there are v, w ∈ S 1 ∩ Ide such that v ∼ w, v.f ∈ S 2 and w.f ∈ S 2 . We need to prove that S 2 = S 2 . Since v ∼ w then 1 (v) = 1 (w) and 2 (v) = 2 (w), which implies proving that the second condition in Definition 35 holds. A small lemma). Note that (i) = [i] ∼ for any i ∈ X and (i) = ⊥ otherwise. This happen by definition when i ∈ Ide, hence we only need to prove the property for This means there is w ∈ Ide such that w ∼ v, w = v and w.f ∈ S. Since w.f ∈ X, then 1 (w.f) = ⊥ = 2 (w.f). But since v ∼ w, then 1 (v) = 1 (w) and 1 (v.f) = 1 (w.f) = ⊥. The same holds or 2 (v.f). Therefore, v.f ∈ X, which is a contradiction. G ∈ G τ ). Now we prove that G is an aliasing graph. Given S ∈ N, we need to check that {τ (i) | i ∈ I τ ∧ (i) = n} is a chain. Let i 1 , i 2 ∈ I τ such that (i 1 ) = (i 2 ) = n. Since by the previous small lemma (i 1 ) = [i 1 ] ∼ and (i 2 ) = [i 2 ] ∼ , we have 1 (i 1 ) = 1 (i 2 ) ∈ N 1 , which means that τ (i 1 ) and τ (i 2 ) are comparable, since G 1 is an aliasing graph. G is the least upper bound of G 1 and G 2 . Finally, we prove that G is the least upper bound of G 1 and G 2 . Consider the map h 1 : By Lemma 100 follows that G is the least upper bound of G 1 and G 2 . Now, we prove that G 1 G 2 in Definition 46 is the greatest lower bound of G 1 and G 2 .
Theorem 102. The aliasing graph G 1 G 2 is the greatest lower bound of G 1 and G 2 .
Proof. Let G = G 1 G 2 . The following holds: G is a pre-aliasing graph). First, we have to prove that ∀S ∈ N, ∀f ∈ Ide, there is at most one outgoing edge from S labeled by f. Let S 1 ∈ N and assume there are edges S 1 f − → S 2 and A small lemma). Note that (i) = [i] ∼ for any i ∈ N and (i) = ⊥ otherwise. The proof is analogous to the one for , hence it is omitted here. G ∈ G τ ). We have to prove that for each S ∈ N, the set {τ (i) | i ∈ I τ ∧ (i) = S} is a nonempty chain. By construction for each S ∈ N, there exists j ∈ I τ such that which is the require property. G is a lower bound of G 1 and G 2 . Let us consider the map h 1 : N 1 → N such that h 1 (n 1 ) = [i] ∼ if i ∈ I τ , 1 (i) = n 1 and [i] ∼ ∈ N, h 1 (n 1 ) = ⊥ otherwise. First, we prove that h 1 is well defined. Let j ∈ I τ such that 1 (j) = n 1 . By definition, i ∼ j and therefore G is the greatest lower bound of G 1 and G 2 . Let G ∈ G τ and assume that G G 1 and G G 2 with the corresponding morphisms h 1 and h 2 (by Theorem 99). First of all, observe that for each i, j ∈ I τ In fact, if [i] ∼ = [j] ∼ , there is a sequence i = i 1 ∼ · · · ∼ i t = j such that 1 (i s ) = 1 (i s+1 ) or 2 (i s ) = 2 (i s+1 ) for each s ∈ {1, . . . , t − 1}. If 1 (i s ) = 1 (i s+1 ), then (i s ) = h 1 ( 1 (i s )) = h 1 ( 1 (i s+1 )) = (i s+1 ). Analogously if 2 (i s ) = 2 (i s+1 ). As a result, we have (i) = (j). Note that this implies: We need to build a morphism h : G → G . For each S ∈ N, consider a qualified identifier i ∈ I τ such that (i) = [i] ∼ = S and we define h (S) = (i). We only need to prove that h is well defined and that it is a morphism. Assume there is j ∈ I τ , with j = i and (j) = [j] ∼ = S. By (A1), we have (i) = (j) and therefore h is well defined. Now, we prove that (i) = h ( (i)). If (i) ∈ N, this is immediate, since h ( (i)) is (i ) for some identifier i such that (i) = (i ). Obviously i = i is a good choice, hence (i) = h ( (i)). If (i) = ⊥, the proof is by contradiction. Assume that (i) = n = ⊥.

A.2.2 Projection and propagation of nullness for aliasing graphs
Lemma 103. If G is a pre-aliasing graph and X ⊆ N, then G| X is a pre-aliasing graph.
Proof. Assume G is a pre-aliasing graph. In G| X , the first condition for pre-aliasing graph is trivially respected, since projection does not introduce any new edge. The second condition is also respected, since no new edges are introduced and labels for nodes in X are preserved. Therefore, G| X is a pre-aliasing graph.

Proof. Let G| X = X E
. First of all, G| X is a pre-aliasing graph by Lemma 103. Now consider n ∈ X and the set Y = {τ (i) | i ∈ I τ ∧ (i) = n}. Note that, for each i ∈ I τ , (i) = n iff (i) = n. This is obvious when i is a variable simply by definition of . If i = v.f and (i) = n, then there is m ∈ N such that (v) = m and m f − → n ∈ E. Since X is backward closed, then m ∈ X, hence (v) = m, m f − → n ∈ E and (i) = n. On the converse, if (i) = n, then (i) = n follows trivially by definition of .
Therefore, Y = {τ (i) | i ∈ I τ ∧ (i) = n} and it is a nonempty chain since G is an aliasing graph. Then G| X is an aliasing graph and τ G| X (n) = τ G (n) for each n ∈ X. In the same way, ψ G| X (n) = ψ G (n) for each n ∈ X.
Proposition 51. If G is a pre-aliasing graph and X ⊆ N is backward closed, then G| X G.
Proof. Let G| X = X E . Consider the partial map h : N X which is the identity on X and undefined on N \ X. We show h : G → G| X is a morphism.
Let i be an identifier. If i is a variable v and (i) = ⊥, then (i) / ∈ X, hence h( (i)) = ⊥ = (i). If (i) = n, then n ∈ X, and h( (i)) = h(n) = n = (i). If i is the qualified identifier v.f, consider the following cases:

A.2.3 The domain of aliasing graphs
The following propositions show that the abstraction of a concrete state is an aliasing graph and that each aliasing graph can be viewed as the abstraction of a concrete state.
Proposition 53. Given σ = φ μ ∈ τ , G = α a (σ ) is an aliasing graph and, for each i ∈ I τ , Proof. First of all, we prove G is a pre-aliasing graph. If l Now we prove (i) = φ(i) for each i ∈ I τ (modulo the fact that null corresponds to ⊥). If i ∈ dom (τ ), the thesis follows directly by definition.
Proof. Let L be a set of locations of the same cardinality of N, and ι : N → L be a bijective map. Consider the state σ = φ μ such that dom (μ) = L and: It is easy to check that σ ∈ τ . Let G = α a (σ ) and we prove that ι : G → G is an isomorphism. Since ι is total and injective, by Proposition 97 it is enough to prove that ι is a graph morphism. In turn, this means proving that, for each identifier i ∈ I τ , ι( (i)) = (i) = φ(i) when φ(i) = null and ι( (i)) = ⊥ when φ(i) = null.

A.3 ALPS graphs
We begin by proving that is a preorder on ALPS-graphs.
Proposition 57. Pre-ALPS graphs are preordered by the relation defined as: Proof. Reflexivity is trivial. Assume now G 1 G 2 and G 2 G 3 . By definition G 1 G 2 and G 2 G 3 and since is a preorder on aliasing graphs, we have that G 1 G 3 . Moreover, 1 (i) ∈ nl 1 ⇒ 2 (i) ∈ nl 2 , 2 (i) ∈ nl 2 ⇒ 3 (i) ∈ nl 3 and therefore 1 (i) ∈ nl 1 ⇒ 3 (i) ∈ nl 3 . Analogously, we have We now prove some properties of cl ↑ and red, and of their interaction.
Proposition 104. (Closures of pre-ALPS graphs). The operators cl ↑ and red are an upper and lower closure operator, respectively. Moreover, if G is closed w.r.t. red, then cl ↑ (G) is closed w.r.t. red, too.
Proof. The fact that red and cl ↑ are closure operators is immediate from their definition. It remains to prove that cl ↑ preserves closedness w.r.t. red.
First of all, every set {n} is G-SH-compatible with any type environment, since κ ∈ C(κ).
Moreover, if there is a nonempty loop involving node n, then n f − → m and there is a path from m to n. By Proposition 95, this means that τ G (n) ∈ C(τ G (m)) and by definition of τ G , τ G (m) ≤ τ G (n).f. Hence, τ G (n) ∈ C(τ G (n).f), τ G (n) ∈ NL and n is G-NL-compatible.

A.3.1 Projections and propagation of nullness
Proposition 64. If G ∈ ALPS τ and X ⊆ N is backward closed, then G| X ∈ ALPS τ .
Proof. It is immediate to check that G| X is closed and that red (G| X ) = G| X (this holds even if X is not backward closed). Moreover, since X is backward closed, then G| X is an aliasing graph and not just a pre-aliasing graph.
Proposition 65. If G is a pre-ALPS graph and X ⊆ N is backward closed, then G| X G.
Proof. Let G = G| X . We know that G| X G by Proposition 51. Now, given the identifier i, assume (i) ∈ nl . This means (i) = n ∈ X and n ∈ nl . By definition, (i) = n and n ∈ nl. Similarly for the sharing component.

A.3.2 Up-and down-closures of Pre-ALPS graphs
We introduce a new preorder on ALPS graphs which is apparently different from the one defined in the main part of the paper. The new definition is based on the concept of morphisms of aliasing graphs, and it is easier to use than the one in Proposition 57, although we will prove them to be equivalent.
Proposition 105. Pre-ALPS graphs are preordered by Proof. We show that is reflexive. Given a pre-ALPS graph G, the only morphism h : G → G is the identity. Then h −1 (sh) = sh and h −1 (nl) = nl, hence G G. Assume now G 1 G 2 and G 2 G 3 with h 2 : G 3 → G 2 and h 1 : Proposition 106. Given pre-ALPS graphs G 1 and G 2 , we have G 1 G 2 iff G 1 G 2 .
Proof. We prove the two implications of the equivalence separately.
Theorem 68. Given a pre-ALPS graph G = G sh nl, the down-closure cl ↓ (G) can be computed as follows. Let sh * nl * be the greatest pair, under the component-wise ordering, such that (2) sh * = sh \ {{m 1 , m 2 } | n ∈ nl * , n Then, we have that b. there exists {n , m} ∈ sh such that n Now, we have to prove that G is the greatest pre-ALPS graph smaller than G and such that G is closed. Let G 1 be a pre-ALPS graph smaller than G such that G 1 is closed. We have to prove that G 1 G .
-(j) = n, and there exists m ∈ nl, such that m − → n ∈ E, k ≤ h and f 1 · · · f k = g 1 · · · g k . In this case, since G 1 G , h 1 (n) = ⊥, h 1 (m) ∈ nl 1 and by Lemma 96, h 1 (m) and f 1 · · · f k = g 1 · · · g k . Let i ≥ 1 be the first index such that f i = g i . Therefore, Since G 1 is closed, by Point 2 of Definition 60 and by a straightforward inductive argument, we have that h 1 (n i−1 ) ∈ nl 1 . Therefore, since G 1 is closed and by Point 4 of Definition 60, we have that {n i , n i } ∈ sh 1 . Now, since G 1 is closed, by Point 3 of Definition 60 and by a straightforward inductive argument, {h 1 (n)} ∈ sh 1 . By Point 1 of Definition 60 h 1 (n) = 1 (j) ∈ N 1 and this contradicts the hypothesis.
Finally, we have to prove that if G is closed w.r.t. red then cl ↓ (G) is a ALPS graph. By previous result, we have only to prove that cl ↓ (G) is closed w.r.t. red. The following holds: sh is G -SH-compatible. Assume {n, m} ∈ sh . By construction, τ G (n) = τ G (n), τ G (m) = τ G (m) and {n, m} ∈ sh. Since by hypothesis G = G sh nl is a pre-ALPS, we have that G graph is an aliasing graph and therefore (τ G (n), τ G (m)) = (τ G (n), τ G (m)) ∈ SH. nl is G -NL-compatible. The proof is analogous to the previous one.

A.3.3 The lattice of ALPS graphs
Among the clauses defining the operation cl ↑ on pre-aliasing graphs, clauses 3, 4, and 5 of Definition 60 enjoy some special properties, since closure w.r.t. these clauses is preserved by counter-image of graph morphisms. This is formally stated by the following definition and lemma.
Definition 107. We say that a pre-ALPS graph G is partially closed when is partially closed, we have that n ∈ h −1 k (nl k ) ⊆ nl and then the thesis.
Lemma 110. Let G 1 and G 2 be ALPS graphs. Then G 1 G 2 is the least upper bound of G 1 and G 2 .
Proof. Let G = G 1 G 2 . By Lemma 109 we have that G 1 G 2 is an ALPS graph. The following holds: G is an upper bound of G 1 and G 2 . By Theorem 101 for k = 1, 2, G k G 1 G 2 = G and let h k : G → G k be the corresponding morphism. We have that Then the thesis follows by Propositions 105 and 106. G is the least upper bound of G 1 and G 2 . Let G be an ALPS graph and assume that G 1 G and G 2 G . Obviously G G since G = G 1 G 2 . Let h 1 : G → G 1 , h 2 : G → G 2 be morphisms of aliasing graphs, they factor through h : G → G and h 1 : Since, by Propositions 105 and 106, h k −1 (sh k ) ⊆ sh , Similarly for the nonlinearity component. Therefore, the proof follows by Propositions 105 and 106.
Lemma 111. Let G 1 and G 2 be ALPS graphs. Then G 1 G 2 is the greatest lower bound of G 1 and G 2 .
Proof. Let G = G 1 G 2 . By definition 72 G = cl ↓ (G ), where • G = G 1 G 2 with morphisms h 1 : G 1 → G and h 2 : G 2 → G; The proof that G is an aliasing graph and that for k = 1, 2, G G k follows by Theorem 102. Let h 1 : G 1 → G , h 2 : G 2 → G be the corresponding morphisms. The following holds: G is a ALPS graph. By Theorem 68, we have only prove that G is closed wrt red. The following holds: sh is G -SH-compatible. Assume {n, m} ∈ sh . By the third point of Lemma 96, for each k ∈ {1, 2}, there are nodes n k , m k ∈ N k s.t. h k (n k ) = n, h k (m k ) = m, τ G k (n k ) = τ G (n), and τ G k (m k ) = τ G (m). Moreover, by definition of sh , {n k , m k } ∈ sh k . Since G k is an ALPS graph, we have (τ G (n), τ G (m)) = (τ G k (n k ), τ G k (m k )) ∈ SH and then the thesis. nl is G -NL-compatible. Assume n ∈ nl . By the third point of Lemma 96, for each k ∈ {1, 2}, there exists n k ∈ N k s.t. h(n k ) = n, τ G k (n k ) = τ G (n) and by definition of nl , n k ∈ nl k . Since G k is an ALPS graph, τ G (n) = τ G k (n k ) ∈ NL. G is a lower bound of G 1 and G 2 . By definition G G . Therefore, it is sufficient to prove that G is a lower bound of G 1 and G 2 . By Theorem 102 for k = 1, 2, G = G 1 G 2 G k . If {n, m} ∈ sh , then h −1 k ({n, m}) ⊆ sh k by definition and therefore h −1 k (sh ) ⊆ sh k . Analogously, if n ∈ nl , then h −1 k (n) ⊆ nl k and then h −1 k (nl ) ⊆ nl k . Hence, for k = 1, 2, by Propositions 105 and 106, G G k .
G is the greatest lower bound of G 1 and G 2 . Let G * be an ALPS graph smaller than G 1 and G 2 , with corresponding morphisms h * 1 and h * 2 , and prove that G * G . By Proposition 106, we have to prove the following facts. G * G . Obviously G * G 1 G 2 = G and therefore there is h * : Let {n, m} ∈ h * −1 (sh * ). Since for k = 1, 2, G * G k , by Propositions 105 By Definition 72 sh = {{n , m } ∈ P 2 (N) | ∀k ∈ {1, 2}.h −1 k ({n , m }) ⊆ sh k }. Therefore, {n, m} ∈ sh and then the thesis. h * −1 (nl * ) ⊆ nl . The proof is similar to the one for the previous point. Therefore, we have that G * G . Moreover since G * is closed and G is the greatest closed pre-ALPS graph smaller than G , we have that G * G.
Proof. The proof that ⊥ = ⊥ τ ∅ ∅ and = τ sh nl are least and greatest element is straightforward. Given a generic ALPS graph G, it is easy to prove that ⊥ G and G . For the latter, if h : τ → G, Lemma 108 ensures that h −1 (nl) ⊆ .nl and h −1 (sh) ⊆ .sh. Now, the proof follows by Lemmas 110 and 111.

A.3.4 The domain of ALPS graphs
The following proposition shows that the abstraction of a concrete state is an ALPS graph.
The proof is similar to the previous one and hence it is omitted.
Lemma 114. Given i ∈ I τ , we have that |i=null is the largest ALPS-graph such that (i) = null.
Proof. Let us denote by N the set of nodes in |i=null and by its labeling function. Note that, if i ∈ Q τ , then N = I τ \ {i}, otherwise i is a variable v and Given an ALPS graph G such that (i) = null, consider the map h : N N such that h(j) = (j) for each j ∈ N . This is a morphism between aliasing graph, since for each identifier j: • If j / ∈ N , then h( (j)) = h(⊥) = ⊥. Moreover, j is either i or an identifier i.f. In both cases, (j) = ⊥. • If j ∈ N , then h( (j)) = h(j) = (j).
As a consequence, we also have that (j) = ⊥ implies (j) = ⊥. By definition of the sharing and nonlinearity components of , it is immediate to check that G |i=null .
Proposition 82. For each G ∈ ALPS τ and i ∈ I τ , G |i=null = G |i=null .
Proof. We prove the two implications of the equality separately.
G |i=null G |i=null . By Proposition 65 we know that G |i=null G, while from Lemma 114 we have that G |i=null |i=null ). The result follows since is the greatest lower bound. G |i=null G |i=null . Let G 1 = G |i=null and G 2 = G |i=null . The following facts hold.

Proposition 115.
Let v ∈ dom (τ ) and let G, G ∈ ALPS, such that G G . Then G |v=null G |v=null .
Proof. The proof is immediate, by observing that by hypothesis and by Proposition 82, G |v=null = G |v=null G |v=null = G |v=null .
Proof. Let G be an ALPS graphs such that (v) = (w). If τ (v) and τ (w) do not form a chain, then (v) = (w) implies that (v) = null = (w), and we have G |v=w = |v=null,w=null by Lemma 114.
If τ (v) and τ (w) do form a chain, let us denote by N the set of nodes in |v=w and by its labeling function. Assume, without loss of generality, that τ (v) ≤ τ (w). Then N = I τ \ {w} \ {w.f | f ∈ dom (τ (w))} and (i) is equal to i, with the proviso that any possible occurrence of w is replaced by v. Consider the map h : N N such that h(j) = (j) for each j ∈ N . This is a morphism between aliasing graphs since for each identifier j: By definition of the sharing and nonlinearity components of , it is immediate to check that G |v=w .
Proof. Similar to the proof of Proposition 83.
where E _ (C _ for the commands) is given in Section 2.2.2 and SE _ (S C _ ) in Figures  20 and 23 (Figures 21 and 22). Remember that for the expressions we have τ = τ + type τ (op) and res ∈ dom (τ ), while for the commands we have τ = τ and res ∈ dom (τ ). The proof is direct for the expressions, while it is by induction for the commands (because commands are defined inductively in Section 2.2). First of all, observe that since in a Galois connection αγ is reductive (Section 2), for each φ μ ∈ γ (G), we have that and therefore by definition of α, null κ We have τ = τ + type τ (null κ) = τ [res → κ]. Then new κ Also in this case we have τ = τ + type τ (new κ) = τ [res → κ]. The proof is similar to that above, since the new object is allocated in a fresh location l, and hence is only reachable from res: For v, we have τ = τ + type τ (v) = τ [res → τ (v)]. Then We have the following possibilities.
On the concrete side, only variables in dom (σ † .φ) can be reached in the computation of I ((φ(v).κ).m)(σ † ). Since dom (σ † .φ) = {this, w 1 , . . . , w n }, it follows that for any variable x ∈ V other we have that φ(x) = φ (x). The same happens on the abstract side, since G |V other = G other . Moreover, for variables in V comp , since on the abstract side we compute ( |V comp ) |{x=y | 1 (x)= 1 (y), x, y∈V comp } , there is nothing to prove.
For any variable x in V alias , since x ∈ dom (σ † .φ) and, by definition of V alias , there exists u ∈ V m such that (x) = (u), it follows that φ (x) = φ (u), which corresponds to the alias mapping in G.
Therefore, we only need to show that the result is correct for variables in V m , which directly follows from the induction hypothesis that I(κ.m)(G ) is correct w.r.t. I ((φ(v).κ).m)(σ † ).

v := exp
Since the composition of correct operations is correct and since we have proved above that the abstract semantics for the expressions are correct with respect to their concrete counterparts, it is enough to prove that the abstract prune operation P v τ = λG ∈ ALPS. prune ((N E [v → (res), res → ⊥]) sh nl) is correct with respect to the corresponding concrete operation setVar v τ = λ(φ μ) ∈ τ . φ| −res [v → φ(res)] μ Let τ = τ | −res and let G ∈ ALPS. We have Then to prove the thesis, by additivity of α, we have to prove that for each φ μ ∈ γ (G), Let G = α(φ μ). By definition {{n 1 , n 2 } ∈ sh | n 1 , n 2 ∈ N 1 } nl ∩ N 1 . Now, the proof is straightforward by definition of P v τ and since by (A6), G = α(φ μ) G.

v.f := exp
Since the composition of correct operations is correct and since we have proved above that the abstract semantics for the expressions is correct w.r.t. their concrete counterparts, it is enough to prove that the abstract operation is correct with respect to the corresponding concrete operation where (x)), (x.f) = (res)} a set of new distinct nodes We have the following possibilities: • (v) = ⊥. In this case, for each φ μ ∈ γ (G), we have that φ(v) = null and then by definition of α, α(setField v.f τ (γ (G))) = α({ undefined }) = ⊥ = P v.f τ (G).
if v = w then com 1 else com 2 Analogously to the previous case, we have to prove that A if eq = λG ∈ ALPS.
if v = null then com 1 else com 2 The proof is analogous to that one of the previous case and hence it is omitted.
{com 1 ; . . . ;com p } The proof of this case follows directly by induction hypothesis.
Theorem 88. The abstract denotational semantics is correct wrt the concrete one.
The first and the second point are the content of Proposition 80 and Theorem 87, respectively. The third point is trivial since adding null variables does not add any node or edge to the graph.