Boolean Functions for Finite-Tree Dependencies^{∗}

Roberto Bagnara Enea Zaffanella

Dept. of Mathematics University of Parma, Italy

bagnara@cs.unipr.it zaffanella@cs.unipr.it

Roberta Gori

Dept. of Computer Science University of Pisa, Italy

gori@di.unipi.it Patricia M. Hill

School of Computing University of Leeds, U.K.

hill@comp.leeds.ac.uk

ABSTRACT

Several logic-based languages, such as Prolog II and its successors, SICStus Prolog and Oz, offer a computation domain including rational trees. Infinite rational trees allow for increased expressivity (cyclic terms can provide efficient representations of grammars and other useful objects) and for faster unification (due to the safe omission of the occurscheck). Unfortunately, the use of infinite rational trees has problems. For instance, many of the built-in and library predicates are ill-defined for such trees and need to be supplemented by run-time checks whose cost may be significant. In a companion paper [3] we have proposed a dataflow analysis aimed at the knowledge of those program variables (the finite variables) that will always be bound to finite terms. The analysis domain introduced in [3] correctly captures the creation and propagation of cyclic terms, but is not capable of propagating the guarantees of finiteness that come from built-in predicates and program annotations. Here we present a domain of Boolean functions that precisely captures how the finiteness of some variables influences the finiteness of other variables. This domain of finite-tree dependencies provides relational information that is important for the precision of the overall finiteness analysis. It also combines obvious similarities, interesting differences and somewhat unexpected connections with classical domains for groundness dependencies.

1. INTRODUCTION

The intended computation domain of most (concurrent and/or constraint and/or functional) logic-based languages includes the algebra of finite trees. Other logic-based languages, such as Prolog II and its successors [10, 12], SICStus

∗The work of the first two authors has been partly supported by MURST project “Certificazione automatica di programmi mediante interpretazione astratta”. The work of the second and fourth authors has been partly supported by EPSRC under grant M05645.

Quaderno 252, Dipartimento di Matematica, Universit� a di Parma, Italy.

Prolog [40], and Oz [38], refer to a computation domain of rational trees. A rational tree is a possibly infinite tree with a finite number of distinct subtrees and, as is the case for finite trees, where each node has a finite number of immediate descendants. These properties will ensure that rational trees, even though infinite in the sense that they admit paths of infinite length, can be finitely represented. One possible representation makes use of connected, rooted, directed and possibly cyclic graphs where nodes are labeled with variable and function symbols as is the case of finite trees.

Applications of rational trees in logic programming include graphics [21], parser generation and grammar manipulation [10, 24], and computing with finite-state automata [10]. Other applications are described in [23] and [25]. Going from Prolog to CLP, [35] combines constraints on rational trees and record structures, while the logic-based language Oz allows constraints over rational and feature trees [38]. The expressive power of rational trees is put to use, for instance, in several areas of natural language processing. Rational trees are used in implementations of the HPSG formalism (Head-driven Phrase Structure Grammar) [36], in the ALE system (Attribute Logic Engine) [8], and in the ProFIT system (Prolog with Features, Inheritance and Templates) [22].

While rational trees allow for increased expressivity, they also come equipped with a surprising number of problems. As we will see, some of these problems are so serious that rational trees must be used in a very controlled way, disallowing them in any context where they are “dangerous”. This, in turn, causes a secondary problem: in order to disallow rational trees in selected contexts one must first detect them, an operation that may be expensive.

The first thing to be aware of is that almost any semanticsbased program manipulation technique developed in the field of logic programming —whether it be an analysis, a transformation, or an optimization— assumes a computation domain of finite trees. Some of these techniques might work with the rational trees but their correctness has only been proved in the case of finite trees. Others are clearly inapplicable. Let us consider a very simple Prolog program:

             list([]).
             list([ |T]) :- list(T).

Most automatic and semi-automatic tools for proving program termination and for complexity analysis agree on the fact that list/1 will terminate when invoked with a ground argument. Consider now the query

             ?- X = [a|X], list(X).

and note that, after the execution of the first rational unification, the variable X will be bound to a rational term containing no variables, i.e., the predicate list/1 will be invoked with X ground. However, if such a query is given to, say, SICStus Prolog, then the only way to get the prompt back is by pressing ^C. The problem stems from the fact that the analysis techniques employed by these tools are only sound for finite trees: as soon as they are applied to a system where the creation of cyclic terms is possible, their results are inapplicable. The situation can be improved by combining these termination and/or complexity analyses by a finiteness analysis providing the precondition for the applicability of the other techniques.

The implementation of built-in predicates is another problematic issue. Indeed, it is widely acknowledged that, for the implementation of a system that provides real support for the rational trees, the biggest effort concerns proper handling of built-ins. Of course, the meaning of ‘proper’ depends on the actual built-in. Built-ins such as copy_term/2 and ==/2 maintain a clear semantics when passing from finite to rational trees. For others, like sort/2, the extension can be questionable:^{1} both raising an exception and answering Y = [a] can be argued to be “the right reaction” to the query

?- X = [a|X], sort(X, Y).

Other built-ins do not tolerate infinite trees in some argument positions. A good implementation should check for finiteness of the corresponding arguments and make sure “the right thing” (i.e., failing or raising an appropriate exception) always happens. However, such behavior appears to be uncommon. A small experiment we conducted on six Prolog implementations with queries like

?- X = 1+X, Y is X.
?- X = [97|X], name(Y, X).
?- X = [X|X], Y =..  [f|X].

resulted in infinite loops, memory exhaustion and/or system thrashing, segmentation faults or other fatal errors. One of the implementations tested, SICStus Prolog, is a professional one and implements run-time checks to avoid most cases where built-ins can have catastrophic effects.^{2} The remaining systems are a bit more than research prototypes, but will clearly have to do the same if they evolve to the stage of production tools. Again, a data-flow analysis aimed at the detection of those variables that are definitely bound to finite terms would allow to avoid a (possibly significant) fraction of the useless run-time checks. Note that what has been said for built-in predicates applies to libraries as well. Even though it may be argued that it is enough for programmers to know that they should not use a particular library predicate with infinite terms, it is clear that the use of a “safe” library, including automatic checks which ensure that such predicates are never called with an illegal argument, will result in more robust systems. With the appropriate data-flow analyses, safe libraries do not have to be inefficient libraries.

Another serious problem is the following: the ISO Prolog standard term ordering cannot be extended to rational trees [M. Carlsson, Personal communication, October

1Even though sort/2 is not required to be a built-in by the standard, it is offered as such by several implementations. 2SICStus 3.8.5 still loops on ?- X = [97|X], name(Y, X).

2000]. Consider the rational trees defined by A = f(B, a) and B = f(A, b). Clearly, A == B does not hold. Since the standard term ordering is total, we must have either A @< B

or B @< A. Assume A @< B. Then f(A, b) @< f(B, a),

since the ordering of terms having the same principal functor is inherited by the ordering of subterms considered in a left-to-right fashion. Thus B @< A must hold, which is a contradiction. A dual contradiction is obtained by assuming B @< A. As a consequence, applying one of the Prolog term-ordering predicates to one or two infinite terms may cause inconsistent results, giving rise to bugs that are exceptionally difficult to diagnose. For this reason, any system that extends ISO Prolog with rational trees ought to detect such situations and make sure they are not ignored (e.g., by throwing an exception or aborting execution with a meaningful message). However, predicates such as the term-ordering ones are likely to be called a significant number of times, since they are often used to maintain structures implementing ordered collections of terms. This is another instance of the efficiency issue mentioned above.

1.1 Detecting the Creation of In�nite Terms

In [3] we have introduced a composite abstract domain for finite-tree analysis, denoted by H × P. The H domain, written with the initial of Herbrand and called the finiteness component, is the direct representation of the property of interest: a set of variables, usually denoted by h, that cannot be bound to infinite terms. Not surprisingly, H is too weak to attain any reasonable precision. One of the reasons is that it lacks any information about the sharing of program variables. Consider how the H domain could safely approximate a unification of the form x = y even assuming that, before the unification, x and y can only be bound to finite terms, i.e., x, y ∈ h. In H there is no information that can exclude that x and y share a common variable, and there is no information to ensure that both x and y are unbound variables. Thus, the abstract unification operator of H cannot exclude that x = y results in the creation of cyclic terms. What is worse, since nothing is known about the sharing of variables between x, y and the other variables of interest, no variable can safely remain in h after the binding.

For this reason, the parametric domain H × P of [3] combines H with a generic domain P (the parameter of the construction) providing sharing information. Here the term “sharing information” is to be understood in its broader meaning, which includes variable aliasing, groundness, linearity, freeness and any other kind of information that can improve the precision on these components, such as explicit structural information. Several domain combinations and abstract operators have been proposed in the literature to capture these properties, and are characterized by different precision/complexity trade-offs (see [6] for an account of some of them).

Sharing information is exploited in H × P for two purposes: detecting when new infinite terms are possibly created (this is done along the lines of [39]) and confining the propagation of those terms as much as possible. As shown in [3], by giving a generic specification for this parameter component in terms of the abstract queries it supports [15], it is possible to define and establish the correctness of the abstract operators on the finite-tree domain independently from any particular domain for sharing analysis.

[figure: P; [3,39]; [6,9]; H; Thm. 25; Thm. 16; Bfun; Thm. 25; Thm. 23; Pos]

Figure 1: The domains discussed in this paper and the information flows between them.

1.2 Propagating Guarantees of Finiteness

The domain H × P captures the negative aspect of termfiniteness, that is, the circumstances under which finiteness can be lost. When a binding has the potential for creating one or more rational terms, the abstract unification operator of H ×P removes from h all the variables that may be bound to non-finite terms.

However, term-finiteness has also a positive aspect: there are cases where a variable is granted to be bound to a finite term and this knowledge can be propagated to other variables. Guarantees of finiteness are provided by several

built-ins like unify_with_occurs_check/2, var/1, name/2,

all the arithmetic predicates, besides those explicitly provided to test for term-finiteness such as the acyclic_term/1 predicate of SICStus Prolog.^{3} The term-finiteness information encoded by H is attribute independent [18], which means that each variable is considered in isolation. What is missing is information concerning how finiteness of one variable affects the finiteness of other variables. This kind of information, usually termed relational information, is not captured at all by H and it is only partially captured by the composite domain H × P of [3].

Here we present a domain of Boolean functions that precisely captures how the finiteness of some variables influences the finiteness of other variables. This domain of finitetree dependencies provides relational information that is important for the precision of the overall finiteness analysis. It also combines obvious similarities, interesting differences and somewhat unexpected connections with classical domains for groundness dependencies.

Finite-tree and groundness dependencies are similar in that they both track covering information (a term s covers t if all the variables in t also occur in s) and share several abstract operations. However, they are different because covering does not tell the whole story. Suppose x and y are free variables before either the unification x = f(y) or the unification x = f(x, y) are executed. In both cases, x will be ground if and only if y will be so. When x = f(y) is the performed unification, this equivalence will also carry over to finiteness. In contrast, when the unification is x = f(x, y), x will never be finite and will be totally independent, as far as finiteness is concerned, from y. Among the unexpected connections is the fact that finite-tree dependencies can improve the groundness information obtained by the usual approaches to groundness analysis.

Figure 1 summarizes the information flows between the domains discussed in this paper.

The paper is structured as follows: the required notations

3On most implementations conforming to the ISO Prolog standard, the predicate acyclic term/1 can be defined by

acyclic term(T) :- unify with occurs check(T,  ).

and preliminary concepts are given in Section 2; the concrete domain for the analysis is presented in Section 3; Section 4 introduces the use of Boolean functions for tracking finitetree dependencies, whereas Section 5 illustrates the interaction between groundness and finite-tree dependencies. The paper is concluded in Section 6 with some final remarks and observations.

2. PRELIMINARIES

2.1 In�nite Terms and Substitutions

For a set S, ℘(S) is the powerset of S, whereas ℘_{f}(S) is the set of all the finite subsets of S. Let Sig denote a possibly infinite set of function symbols, ranked over the set of natural numbers. Let Vars denote a denumerable set of variable symbols, disjoint from Sig. Then Terms denotes the free algebra of all (possibly infinite) terms in the signature Sig having variables in Vars. Thus a term can be seen as an ordered labeled tree, possibly having some infinite paths and possibly containing variables: every inner node is labeled with a function symbol in Sig with a rank matching the number of the node’s immediate descendants, whereas every leaf is labeled by either a variable symbol in Vars or a function symbol in Sig having rank 0 (a constant). It is assumed that Sig contains at least two distinct function symbols, one having rank 0 (so that there exist finite terms not containing variables) and one with rank greater than 0 (so that there exist infinite terms).

A path p ∈ (ℕ \ {0})^{⋆} is any finite sequence of (non-zero) natural numbers. The empty path is denoted by ϵ, whereas i.p denotes the path obtained by concatenating the sequence formed by the natural number i ≠ 0 with the sequence of the path p. Given a path p and a (possibly infinite) term t ∈ Terms, we denote by t[p] the subterm of t found by following path p. Formally,

t[p] = \begin{cases}t & if p = ϵ; \\ t_{i}[q] & if p = i . q ∧ (1 ≤ i ≤ n) ∧ t = f(t_{1}, …, t_{n}). \end{cases}

Note that t[p] is only defined for those paths p actually corresponding to subterms of t.

If t ∈ Terms then vars(t) denotes the set of variables occurring in t. If vars(t) = ∅ then t is said to be ground; t is a finite term (or Herbrand term) if it contains a finite number of occurrences of function symbols. The sets of all ground and finite terms are denoted by GTerms and HTerms, respectively.

The function size: HTerms → ℕ, for each t ∈ HTerms, is defined by

size(t) =^{def} \begin{cases}1, & if t ∈ Vars; \\ 1 + ∑_{i=1}^{n} size(t_{i}), & if t = f(t_{1}, …, t_{n}). \end{cases}

A substitution is a total function σ: Vars → HTerms that is the identity almost everywhere; in other words, the domain of σ, defined as

dom(σ) =^{def} { x ∈ Vars | σ(x) ≠ x },

is a finite set of variables.

Given a substitution σ: Vars → HTerms, the symbol ‘σ’ also denotes the function σ: HTerms → HTerms defined as follows, for each term t ∈ HTerms:

σ(t) =^{def} \begin{cases}t, & if t is a constant symbol; \\ σ(t), & if t ∈ Vars; \\ f(σ(t_{1}), …, σ(t_{n})), & if t = f(t_{1}, …, t_{n}). \end{cases}

If t ∈ HTerms, we write tσ to denote σ(t).

If x ∈ Vars and t ∈ HTerms \ {x}, then x ↦ t is called a binding. The set of all bindings is denoted by Bind. Substitutions are conveniently denoted by the set of their bindings. Thus a substitution σ is identified with the (finite) set

{ x ↦ σ(x) | x ∈ dom(σ) }.

We denote by vars(σ) the set of all variables occurring in the bindings of σ.

A substitution is said to be circular if, for n > 1, it has the form

{x_{1} ↦ x_{2}, …, x_{n−1} ↦ x_{n}, x_{n} ↦ x_{1}},

where x_{1}, …, x_{n} are distinct variables. A substitution is in rational solved form (RSF) if it has no circular subset. The set of all substitutions in rational solved form is denoted by RSubst.

The composition of substitutions is defined in the usual way. Thus τ ∘ σ is the substitution such that, for all terms t ∈ HTerms,

(τ ∘ σ)(t) = τ(σ(t))

and has the formulation

τ ∘ σ = { x ↦ xστ | x ∈ dom(σ), x ≠ xστ }

∪ { x ↦ xτ | x ∈ dom(τ) \ dom(σ) }.

As usual, σ^{0} denotes the identity function (i.e., the empty substitution) and, when i ∈ ℕ with i > 0, σ^{i} denotes the substitution (σ ∘ σ^{i−1}).

For each σ ∈ RSubst, s ∈ HTerms, the sequence of finite terms

σ^{0}(s), σ^{1}(s), σ^{2}(s), …

converges to a (possibly infinite) term, denoted by σ^{∞}(s) [27, 31]. Therefore, the function rt: HTerms × RSubst → Terms such that

rt(s, σ) =^{def} σ^{∞}(s)

is well defined. In general, this function is not a substitution: while having a finite domain, its “bindings” x ↦ t can map a domain variable x into a term t ∈ Terms \ HTerms.

Some of the proofs in the following sections rely on the following properties of the ‘rt’ function.

Proposition 1. Let σ ∈ RSubst and t ∈ HTerms. Then

vars(rt(t, σ))∩ dom(σ) = ∅,  (1a)
rt(t, σ) ∈ HTerms ⟺ ∃i ∈ ℕ . rt(t, σ) = tσ^{i}.  (1b)

Proof. (1a) Let x ∈ dom(σ) and, towards a contradiction, sup-

pose x ∈ vars(rt(s, σ)). Thus, there exists a finite path p such that x = rt(s, σ)[p]. Thus, by definition of ‘rt’, there exists an index i ∈ ℕ such that x = σ^{i}(s)[p]. Since x ∈ dom(σ), then x ≠ xσ, so that x ≠ σ^{i+1}(s)[p]. Also note that, being σ ∈ RSubst, σ contains no circular subsets, so that we have x ≠ σ^{j}(s)[p], for each index j > i. This implies x ≠ rt(s, σ)[p], which is a contradiction. Since no such finite path p can exist, we can conclude x ∉ vars(rt(s, σ)).

(1b) Since substitutions map finite terms into finite terms, a finite number of applications cannot produce an infinite term, so that the left implication holds. Proving the right implication by contraposition, suppose that rt(t, σ) ≠ tσ^{i}, for all i ∈ ℕ. Then, by definition of ‘rt’, we have tσ^{i} ≠ tσ^{i+1}, for all i ∈ ℕ. Letting n ∈ ℕ be the number of bindings in σ ∈ RSubst, for all i ∈ ℕ it holds size(tσ^{i}) < size(tσ^{i+n}), because σ has no circular subsets. Thus rt(t, σ) ∉ HTerms, because there is no finite upper bound to the number of function symbols occurring in rt(t, σ).

2.2 Equations

An equation is of the form s = t where s, t ∈ HTerms. Eqs denotes the set of all equations. A substitution σ may be regarded as a finite set of equations, that is, as the set { x = t | x ↦ t ∈ σ }. We say that a set of equations e is in rational solved form if { s ↦ t | (s = t) ∈ e } ∈ RSubst. In the rest of the paper, we will often write a substitution σ ∈ RSubst to denote a set of equations in rational solved form (and vice versa).

Some logic-based languages, such as Prolog II, SICStus and Oz, are based on RT , the theory of rational trees [10, 11]. This is a syntactic equality theory (i.e., a theory where the function symbols are uninterpreted), augmented with a uniqueness axiom for each substitution in rational solved form. Informally speaking these axioms state that, if a ground rational tree is assigned to each of the non-domain variables of a substitution, then this substitution uniquely defines a ground rational tree for each of its domain variables. Thus, any set of equations in rational solved form is, by definition, satisfiable in RT .^{4}

Given a set of equations e ∈ ℘_{f}(Eqs) that is satisfiable in RT , a substitution σ ∈ RSubst is called a solution for e in RT if RT ⊢ ∀(σ → e). If in addition vars(σ) ⊆ vars(e), then σ is said to be a relevant solution for e. Finally, σ is a most general solution for e in RT if RT ⊢ ∀(σ ↔ e). In this paper, the set of all the relevant most general solution for e in RT will be denoted by mgs(e).

Definition 1. (↓(·): RSubst → ℘(RSubst).) The function ↓(·): RSubst → ℘(RSubst) is defined, for each σ ∈ RSubst, by

↓ σ =^{def} { τ ∈ RSubst | ∃σ′ ∈ RSubst . τ ∈ mgs(σ ∪ σ′) }.

The function ↓(·) corresponds to the closure by entailment in the equality theory RT .

Proposition 2. Let σ ∈ RSubst. Then

↓ σ = { τ ∈ RSubst | RT ⊢ ∀(τ → σ) }.

Proof. The result follows by the following chain of equivalences, where the left implication in the last step is obtained by taking σ′ = τ.

4Note that being in rational solved form is a very weak property. Indeed, unification algorithms returning a set of equations in rational solved form are allowed to be much more “lazy” than one would usually expect. We refer the interested reader to [29, 30, 32] for details on the subject.

τ ∈ ↓ σ ⟺ ∃σ′ ∈ RSubst . τ ∈ mgs(σ ∪ σ′)

⟺ ∃σ′ ∈ RSubst . RT ⊢ ∀(τ ↔ (σ ∪ σ′))

⟺ ∃σ′ ∈ RSubst .

RT ⊢ (∀(τ → σ) ∧ ∀(τ → σ′)

∧ ∀((σ ∪ σ′) → τ))

⟺ RT ⊢ ∀(τ → σ).

Notice that, since entailment is a transitive relation, we have, for all σ, τ, υ ∈ RSubst,

υ ∈ ↓ τ ∧ τ ∈ ↓ σ ⟹ υ ∈ ↓ σ.

The following results are needed in the sequel: Lemma 3 is a simple generalization of [26, Lemma 1]; Lemma 4 has been proved in [26]; Lemma 5 has been proved in [3]; finally, Lemma 6, which is new, relates the function ‘rt’ and the concept of equality under the theory RT .

Lemma 3. Let σ ∈ RSubst and {x ↦ t} ∈ RSubst be both satisfiable in the equality theory T, where x ∉ dom(σ) and vars(t) ∩ dom(σ) = ∅. Let also σ′ =^{def} σ ∪ {x ↦ t}. Then σ′ ∈ RSubst and σ′ is satisfiable in T.

Proof. Note that σ′ is a substitution, since σ ∈ RSubst and x ∉ dom(σ). Moreover, as vars(t) ∩ dom(σ) = ∅, σ′ cannot contain circular subsets. Hence, σ′ ∈ RSubst.

Since both σ and {x ↦ t} are satisfiable in T, we have

T ⊢ ∀Vars \ dom(σ) : ∃ dom(σ) . σ,
T ⊢ ∀Vars \ {x} : ∃x . {x = t}.

Hence, since x ∉ dom(σ),

T ⊢ ∀Vars \ (dom(σ) ∪ {x}) :

∃(dom(σ) ∪ {x}) . σ ∪ {x = t}.

Thus σ′ is satisfiable in T.

Lemma 4. Let T be an equality theory, σ ∈ RSubst and t ∈ HTerms. Then

T ⊢ ∀(σ → (t = tσ)).

Lemma 5. Let s ∈ GTerms ∩ HTerms and t ∈ HTerms, where size(t) > size(s). Let also T be any syntactic equality theory. Then T ⊢ ∀(s ≠ t).

Lemma 6. Let σ ∈ RSubst and s, t ∈ HTerms, where RT ⊢ ∀(σ → (s = t)). Then rt(s, σ) = rt(t, σ).

Proof. Suppose, towards a contradiction, that it holds rt(s, σ) ≠ rt(t, σ). Then, there must exist a finite path p such that:

a. x = rt(s, σ)[p] ∈ Vars\dom(σ), y = rt(t, σ)[p] ∈ Vars\ dom(σ) and x ≠ y; or

b. x = rt(s, σ)[p] ∈ Vars \ dom(σ) and r = rt(t, σ)[p] ∉ Vars or, symmetrically, r = rt(s, σ)[p] ∉ Vars and x = rt(t, σ)[p] ∈ Vars \ dom(σ); or c. r_{1} = rt(s, σ)[p] ∉ Vars, r_{2} = rt(t, σ)[p] ∉ Vars and r_{1}

and r_{2} have different principal functors.

Then, by definition of ‘rt’, there must exists an index i ∈ ℕ such that one of these holds:

1. x = sσ^{i}[p] ∈ Vars\dom(σ), y = tσ^{i}[p] ∈ Vars\dom(σ) and x ≠ y; or

2. x = sσ^{i}[p] ∈ Vars \ dom(σ) and r = tσ^{i}[p] ∉ Vars or, symmetrically, r = sσ^{i}[p] ∉ Vars and x = tσ^{i}[p] ∈ Vars \ dom(σ); or

3. r_{1} = sσ^{i}[p] ∉ Vars and r_{2} = tσ^{i}[p] ∉ Vars have different principal functors.

By Lemma 4, we have RT ⊢ ∀(σ → (sσ^{i} = tσ^{i})); from this, since RT is a syntactic equality theory, we obtain that

RT ⊢ ∀(σ → (sσ^{i}[p] = tσ^{i}[p])).  (2)

We now prove that each case leads to a contradiction. Consider case 1. Let r_{1}, r_{2} ∈ GTerms ∩ HTerms be terms

having different principal functors, so that RT ⊢ ∀(r_{1} ≠ r_{2}). By Lemma 3, we have σ′ = σ ∪ {x ↦ r_{1}, y ↦ r_{2}} ∈ RSubst is satisfiable and RT ⊢ ∀(σ′ → σ), RT ⊢ ∀(σ′ → (x = r_{1})), RT ⊢ ∀(σ′ → (y = r_{2})). This is a contradiction, since, by (2), we have RT ⊢ ∀(σ → (x = y)).

Consider case 2. Without loss of generality, consider the first subcase, where x = sσ^{i} and r = tσ^{i}[p] ∉ Vars. Let r′ ∈ GTerms ∩ HTerms be such that r and r′ have different principal functors, so that RT ⊢ ∀(r ≠ r′). By Lemma 3, σ′ = σ ∪ {x ↦ r′} ∈ RSubst is satisfiable; we also have RT ⊢ ∀(σ′ → σ) and RT ⊢ ∀(σ′ → (x = r′)). This is a contradiction, since, by (2), RT ⊢ ∀(σ → (x = r)).

Finally, consider case 3. In this case RT ⊢ ∀(r_{1} ≠ r_{2}). This immediately leads to a contradiction, since, by (2), RT ⊢ ∀(σ → (r_{1} = r_{2})).

2.3 Boolean Functions

We now introduce Boolean functions based on the notion of Boolean valuation. An important class of Boolean functions that has been used for data-flow analysis of logic-based languages is Pos [1], introduced in [33] under the name Prop and further refined and studied in [13, 34].

Definition 2. (Boolean valuations.) Consider any finite set of variables VI ∈ ℘_{f}(Vars) and let 𝔹 =^{def} {0, 1}. The set of Boolean valuations over VI is given by

Bval =^{def} VI → 𝔹.

For each a ∈ Bval, each x ∈ VI, and each c ∈ 𝔹 the valuation a[c/x] ∈ Bval is given, for each y ∈ VI, by

a[c/x](y) =^{def} \begin{cases}c, & if x = y; \\ a(y), & otherwise. \end{cases}

For X = {x_{1}, …, x_{k}} ⊆ VI, we write a[c/X] as a shorthand for a[c/x_{1}] ⋯ [c/x_{k}]. The distinguished elements 0, 1 ∈ Bval are given by

0 =^{def} λx ∈ VI . 0,
1 =^{def} λx ∈ VI . 1.

Definition 3. (Boolean functions.) The set of Boolean functions over VI is

Bfun =^{def} Bval → 𝔹.

Bfun is partially ordered by the relation ⊧ where, for each ϕ, ψ ∈ Bfun,

ϕ ⊧ ψ ⟺^{def} (∀a ∈ Bval : ϕ(a) = 1 ⟹ ψ(a) = 1).

The distinguished elements ⊤, ⊥ ∈ Bfun are the functions defined, respectively, by

⊥ =^{def} λa ∈ Bval . 0,
⊤ =^{def} λa ∈ Bval . 1.

For ϕ ∈ Bfun, x ∈ VI, and c ∈ 𝔹, the Boolean function ϕ[c/x] ∈ Bfun is given, for each a ∈ Bval, by

ϕ[c/x](a) =^{def} ϕ(a[c/x]).

When X ⊆ VI, ϕ[c/X] is defined in the expected way. If ϕ ∈ Bfun and x, y ∈ VI the function ϕ[y/x] ∈ Bfun is given, for each a ∈ Bval, by

ϕ[y/x](a) =^{def} ϕ(a[a(y)/x]).

Boolean functions are constructed from the elementary functions corresponding to variables and by means of the usual logical connectives. Thus x denotes the Boolean function ϕ such that, for each a ∈ Bval, ϕ(a) = 1 if and only if a(x) = 1. For ϕ_{1}, ϕ_{2} ∈ Bfun, we write ϕ_{1} ∧ ϕ_{2} to denote the function ϕ such that, for each a ∈ Bval, ϕ(a) = 1 if and only if both ϕ_{1}(a) = 1 and ϕ_{2}(a) = 1. A variable is restricted away using Schröder’s elimination principle [37]:

∃x . ϕ =^{def} ϕ[1/x] ∨ ϕ[0/x].

Existential quantification is both monotonic and extensive on Bfun. The other Boolean connectives and quantifiers are handled similarly.

Pos ⊂ Bfun consists precisely of those functions assuming the true value under the everything-is-true assignment, i.e.,

Pos =^{def} { ϕ ∈ Bfun | ϕ(1) = 1 }.

In what follows we will need the notion of entailed and disentailed variables of a Boolean function.

Definition 4. (True and false variables.) For a function ϕ ∈ Bfun, the set of variables necessarily true for ϕ and the set of variables necessarily false for ϕ are given, respectively, by

true(ϕ) =^{def} { x ∈ VI | ∀a ∈ Bval : ϕ(a) = 1 ⟹ a(x) = 1 },
false(ϕ) =^{def} { x ∈ VI | ∀a ∈ Bval : ϕ(a) = 1 ⟹ a(x) = 0 }.

3. THE CONCRETE DOMAIN

Throughout the paper, we assume a knowledge of the basic concepts of abstract interpretation theory [16, 19].

For the purpose of this paper, we assume a concrete domain consisting of pairs of the form (Σ, V), where V is a finite set of variables of interest and Σ is a (possibly infinite) set of substitutions in rational solved form.

Definition 5. (The concrete domain.) Let

D^{♭} =^{def} ℘(RSubst) × ℘_{f}(Vars).

If (Σ, V) ∈ D^{♭}, then (Σ, V) represents the (possibly infinite) set of first-order formulas

{ ∃Δ . σ | σ ∈ Σ, Δ = vars(σ) \ V }

where σ is interpreted as the logical conjunction of the equations corresponding to its bindings. The operation of projecting x ∈ Vars away from (Σ, V) ∈ D^{♭} is defined as follows:

∃∃ x . (Σ, V)

=^{def} \{ σ′ ∈ RSubst | \begin{matrix}σ ∈ Σ, \\ \overline{V} = Vars \ V, \\ RT ⊢ ∀(∃\overline{V} . (σ′ ↔ ∃x . σ)) \end{matrix} \}.

Concrete domains for constraint languages would be similar. If the analyzed language allows the use of constraints on various domains to restrict the values of the variable leaves of rational trees, the corresponding concrete domain would have one or more extra components to account for the constraints (see [4] for an example).

The concrete element

({{x ↦ f(y)}}, {x, y})

expresses a dependency between x and y. In contrast,

({{x ↦ f(y)}}, {x})

only constrains x. The same concept can be expressed by saying that in the first case the variable name ‘y’ matters, but it does not in the second case. Thus, the set of variables of interest is crucial for defining the meaning of the concrete and abstract descriptions. Despite this, always specifying the set of variables of interest would significantly clutter the presentation. Moreover, most of the needed functions on concrete and abstract descriptions, preserve the set of variables of interest. For these reasons, we assume the existence of a set VI ∈ ℘_{f}(Vars) that contains, at each stage of the analysis, the current variables of interest.^{5} As a consequence, when the context makes it clear that Σ ∈ ℘(RSubst), we will write Σ ∈ D^{♭} as a shorthand for (Σ, VI) ∈ D^{♭}.

3.1 Operators on Substitutions in RSF

There are cases when an analysis tries to capture properties of the particular substitutions computed by a specific rational unification algorithm. For instance, this is the case for analyses tracking structure sharing for the purpose of compile-time garbage collection, or providing upper bounds to the amount of memory needed to perform a given computation. More often the interest is on properties of the rational trees themselves. In these cases it is possible to define abstraction and concretization functions that are independent from the finite representations actually computed. Moreover, it is important that these functions precisely capture the properties under investigation, so as to avoid any unnecessary precision loss.

5This parallels what happens in the efficient implementation of data-flow analyzers. In fact, almost all the abstract domains currently in use do not need to represent explicitly the set of variables of interest. In contrast, this set is maintained externally and in a unique copy, typically by the fixpoint computation engine.

Pursuing this goal requires the ability to observe properties of (infinite) rational trees while just dealing with one of their finite representations. This is not always an easy task, since even simple properties can be “hidden” when using non-idempotent substitutions. For instance, when rt(x, σ) ∈ GTerms \ HTerms is an infinite and ground rational tree, all of its finite representations in RSubst will map the variable x into a finite term that is not ground.

These are the motivations behind the introduction of two computable operators on substitutions that will later be used to define the concretization functions for the considered abstract domains. First, the groundness operator ‘gvars’ captures the set of variables that are mapped to ground rational trees by the ‘rt’ function. We define it by means of the occurrence operator ‘occ’ introduced in [26].

Definition 6. (Occurrence functions.) For each n ∈ ℕ, the occurrence function occ_{n}: RSubst × Vars → ℘_{f}(Vars) is defined, for each σ ∈ RSubst and each v ∈ Vars, by

occ_{0}(σ, v) =^{def} {v} \ dom(σ)

and, for n > 0, by

occ_{n}(σ, v) =^{def} { y ∈ Vars | vars(yσ) ∩ occ_{n−1}(σ, v) ≠ ∅ }.

For each σ ∈ RSubst, v ∈ Vars and each n ≥ 0, we have occ_{n}(σ, v) ⊆ vars(σ)∪{v}, where vars(σ) is a finite set. Also, occ_{n}(σ, v) ⊆ occ_{n+1}(σ, v). Thus the following operator is finitely computable.

Definition 7. (Occurrence operator.) The occurrence operator occ: RSubst × Vars → ℘_{f}(Vars) is given, for each substitution σ ∈ RSubst and v ∈ Vars, by

occ(σ, v) =^{def} occ_{ℓ}(σ, v)

where ℓ ∈ ℕ is such that occ_{ℓ}(σ, v) = occ_{n}(σ, v) for all n ≥ ℓ.

Definition 8. (Groundness operator.) The groundness operator gvars: RSubst → ℘_{f}(Vars) is given, for each substitution σ ∈ RSubst, by

gvars(σ) =^{def} { y ∈ dom(σ) | ∀v ∈ vars(σ) : y ∉ occ(σ, v) }.

The finiteness operator ‘hvars’, introduced in [3], captures the set of variables that ‘rt’ maps to finite terms.

Definition 9. (Finiteness functions.) For each n ∈ ℕ, the finiteness function hvars_{n}: RSubst → ℘(Vars) is defined, for each σ ∈ RSubst, by

hvars_{0}(σ) =^{def} Vars \ dom(σ)

and, for n > 0, by

hvars_{n}(σ) =^{def} hvars_{n−1}(σ)

∪ { y ∈ dom(σ) | vars(yσ) ⊆ hvars_{n−1}(σ) }.

Observe that, for each σ ∈ RSubst and each n ∈ ℕ with n > 0, we have hvars_{n}(σ) ⊆ hvars_{n+1}(σ). Note also that Vars \ hvars_{n}(σ) ⊆ dom(σ) is a finite set. By these two properties, the following fixpoint computation is well defined and finitely computable.

Definition 10. (Finiteness operator.) The finiteness operator hvars: RSubst → ℘(Vars) is given, for each substitution σ ∈ RSubst, by

hvars(σ) =^{def} hvars_{ℓ}(σ)

where ℓ =^{def} ℓ(σ) ∈ ℕ is such that hvars_{ℓ}(σ) = hvars_{n}(σ) for each n ≥ ℓ.

The following proposition summarizes two results proved in [26] and [3], and shows that the functions ‘gvars’ and ‘hvars’ precisely capture the intended properties.

Proposition 7. Let σ ∈ RSubst and x ∈ Vars. Then

y ∈ gvars(σ) ⟺ rt(y, σ) ∈ GTerms,  (7a)
y ∈ hvars(σ) ⟺ rt(y, σ) ∈ HTerms.  (7b)

Corollary 8. Let σ ∈ RSubst and t ∈ HTerms. Then

vars(t) ⊆ gvars(σ) ⟺ rt(t, σ) ∈ GTerms,  (8a)
vars(t) ⊆ hvars(σ) ⟺ rt(t, σ) ∈ HTerms.  (8b)

Example 1. Let

σ = {x ↦ f(y, z), y ↦ g(z, x), z ↦ f(a)},
τ = {v ↦ g(z, w), x ↦ f(y), y ↦ g(w), z ↦ f(v)}.

Then

gvars(σ) ∩ vars(σ) = {x, y, z},
hvars(τ) ∩ vars(τ) = {w, x, y}.

The following proposition states how ‘gvars’ and ‘hvars’ behave with respect to the further instantiation of variables.

Proposition 9. Let σ, τ ∈ RSubst, where τ ∈ ↓ σ. Then

hvars(σ) ⊇ hvars(τ),  (9a)
gvars(σ) ∩ hvars(σ) ⊆ gvars(τ) ∩ hvars(τ).  (9b)

Proof.

(9a). Suppose x ∈ hvars(τ)\hvars(σ). Then, by case (7b) of Proposition 7, rt(x, τ) ∈ HTerms. By Proposition 1, there exists i ∈ ℕ such that rt(x, τ) = xτ^{i} and also vars(xτ^{i}) ∩ dom(τ) = ∅. Let t ∈ GTerms ∩ HTerms and

υ =^{def} { y ↦ t | y ∈ vars(xτ^{i}) }.

Then, by Lemma 3, τ′ =^{def} τ ∪ υ ∈ RSubst is satisfiable. Moreover xτ^{i}τ′ ∈ GTerms ∩ HTerms. Let n =^{def} size(xτ^{i}τ′). Note that, since rt(x, σ) ∉ HTerms, there exists j ∈ ℕ such that size(xσ^{j}) > n. Therefore, by Lemma 5,

RT ⊢ ∀(xτ^{i}τ′ ≠ xσ^{j}).  (6)

Also, by Lemma 4, RT ⊢ ∀(σ → (x = xσ^{j})) and RT ⊢ ∀(τ → (x = xτ^{i})). By definition, τ′ ∈ ↓ τ and, by hypothesis, τ ∈ ↓ σ, so that τ′ ∈ ↓ σ. Thus, by Proposition 2 and transitivity, we have RT ⊢ ∀(τ′ → (xτ^{i} = xσ^{j})). Applying Lemma 4, we obtain RT ⊢ ∀(τ′ → (xτ^{i}τ′ = xσ^{j})), which contradicts (6).

(9b). Suppose x ∈ hvars(σ) ∩ gvars(σ). Then, by Proposition 7, rt(x, σ) ∈ GTerms ∩ HTerms. Thus, by case (1b) of Proposition 1, there exists i ∈ ℕ such that rt(x, σ) = xσ^{i} and also vars(xσ^{i}) = ∅. Thus rt(xσ^{i}, τ) = xσ^{i}. Since, by hypothesis, τ ∈ ↓ σ, by Lemma 4 and transitivity we obtain RT ⊢ ∀(τ → (x = xσ^{i})). Thus, by Lemma 6, rt(x, τ) = rt(xσ^{i}, τ) = xσ^{i}. Therefore, by Proposition 7, x ∈ gvars(τ) ∩ hvars(τ).

The next result shows how ‘hvars’ behaves with respect to projecting away some of its variables.

Proposition 10. Let σ, τ ∈ RSubst and let W ⊆ Vars, where RT ⊢ ∀(∃W . σ ↔ ∃W . τ). Then

hvars(σ) \ W = hvars(τ) \ W.

Proof. Consider a variable z ∈ hvars(σ)\W. We assume that z ∉ hvars(τ) to obtain a contradiction.

By case (7b) of Proposition 7, rt(z, σ) ∈ HTerms. By Proposition 1, there exists i ∈ ℕ such that rt(z, σ) = zσ^{i} and vars(zσ^{i}) ∩ dom(σ) = ∅.

Take t ∈ GTerms ∩ HTerms and let

υ =^{def} { y ↦ t | y ∈ vars(zσ^{i}) }.

By Lemma 3, σ′ =^{def} σ ∪ υ ∈ ↓ σ is satisfiable. Thus, by Proposition 2, we have

RT ⊢ ∀(σ′ → σ).  (7)

By the definition of σ′, zσ^{i}σ′ ∈ GTerms ∩ HTerms. As z ∉ hvars(τ), there exists j ∈ ℕ such that size(zτ^{j}) > size(zσ^{i}σ′). Thus, by Lemma 5,

RT ⊢ ∀(zσ^{i}σ′ ≠ zτ^{j}).  (8)

By applying Lemma 4, we have RT ⊢ ∀(σ → (z = zσ^{i})) and RT ⊢ ∀(σ′ → (zσ^{i} = zσ^{i}σ′)). Thus, by (7),

RT ⊢ ∀(σ′ → (z = zσ^{i}σ′)).  (9)

Using (7), the hypothesis and the logically true statement ∀(σ → ∃W . σ), we obtain RT ⊢ ∀(σ′ → ∃W . τ). By Lemma 4, we have RT ⊢ ∀(τ → (z = zτ^{j})); thus, as RT is a first-order theory, RT ⊢ ∀(∃W . τ → ∃W . (z = zτ^{j})). Therefore, by transitivity, we obtain

RT ⊢ ∀(σ′ → ∃W . (z = zτ^{j})).  (10)

Observe now that vars(z = zσ^{i}σ′) = {z} and, as a consequence, we have vars(z = zσ^{i}σ′) ∩ W = ∅. Therefore, by (9) and (10), we obtain

RT ⊢ ∀(σ′ → (z = zσ^{i}σ′ ∧ ∃W . z = zτ^{j}))

⟺ RT ⊢ ∀(σ′ → ∃W . (z = zσ^{i}σ′ ∧ z = zτ^{j}))

⟺ RT ⊢ ∀(σ′ → ∃W . (zσ^{i}σ′ = zτ^{j})).

But this contradicts (8), so that the assumption was false and z ∈ hvars(τ). As the choice of z was arbitrary, we have

hvars(σ) \ W ⊆ hvars(τ) \ W.

The reverse inclusion follows by symmetry.

4. FINITE-TREE DEPENDENCIES

Any finite-tree domain must keep track of those variables that are definitely bound to finite terms, since this is the final information delivered by the analysis. In [3] we have introduced the composite abstract domain H ×P, where the set of such variables is explicitly represented in the finiteness component H.

Definition 11. (The finiteness component H.) The set H =^{def} ℘(VI), partially ordered by reverse subset inclusion, is called finiteness component. The concretization function γ_{H}: H → ℘(RSubst) is given, for each h ∈ H, by

γ_{H}(h) =^{def} { σ ∈ RSubst | hvars(σ) ⊇ h }.

As proven in [3], equivalent substitutions in rational solved form have the same finiteness abstraction.

Proposition 11. Let σ, τ ∈ RSubst, where σ ∈ γ_{H}(h) and RT ⊢ ∀(σ ↔ τ). Then τ ∈ γ_{H}(h).

As explained before, the precision of the finite-tree analysis of [3] is highly dependent on the precision of the generic component P. The information provided by P on groundness, freeness, linearity, and sharing of variables is exploited, in the combination H × P, to circumscribe as much as possible the creation and propagation of cyclic terms. However, finite-tree analysis can also benefit from other kinds of relational information. In particular, we now show how finitetree dependencies allow to obtain a positive propagation of finiteness information.

Let us consider the finite terms t_{1} = f(x), t_{2} = g(y), and t_{3} = h(x, y): it is clear that, for each assignment of rational terms to x and y, t_{3} is finite if and only if t_{1} and t_{2} are so. We will capture this by the Boolean formula t_{3} ↔ (t_{1} ∧ t_{2}).^{6} The reasoning is based on the following facts:

1. t_{1}, t_{2}, and t_{3} are finite terms, so that the finiteness of their instances depends only on the finiteness of the terms that take the place of x and y.

2. vars(t_{3}) ⊇ vars(t_{1}) ∪ vars(t_{2}), that is, t_{3} covers both t_{1} and t_{2}; this means that, if an assignment to the variables of t_{3} produces a finite instance of t_{3}, that very assignment will necessarily result in finite instances of t_{1} and t_{2}. Conversely, an assignment producing nonfinite instances of t_{1} or t_{2} will forcibly result in a nonfinite instance of t_{3}.

3. Similarly, t_{1} and t_{2}, taken together, cover t_{3}.

The important point to notice is that the indicated dependency will keep holding for any further simultaneous instantiation of t_{1}, t_{2}, and t_{3}. In other words, such dependencies are preserved by forward computations (which proceed by consistently instantiating program variables).

Consider the abstract binding x ↦ t where t is a finite term such that vars(t) = {y_{1}, …, y_{n}}. After this binding has been successfully performed, the destinies of x and t concerning term-finiteness are tied together: forever. This tie can be described by the dependency formula

x ↔ (y_{1} ∧ ⋯ ∧ y_{n}),  (11)

meaning that x will be bound to a finite term if and only if y_{i} is bound to a finite term, for each i = 1, …, n. While the dependency expressed by (11) is a correct description of any computation state following the application of the binding x ↦ t, it is not as precise as it could be. Suppose that x and y_{k} are indeed the same variable. Then (11) is logically equivalent to

x → (y_{1} ∧ ⋯ ∧ y_{k−1} ∧ y_{k+1} ∧ ⋯ ∧ y_{n}).  (12)

6The introduction of such Boolean formulas, called dependency formulas, is originally due to P. W. Dart [20].

Correct: whenever x is bound to a finite term, all the other variables will be bound to finite terms. The point is that x has just been bound to a non-finite term, irrevocably: no forward computation can change this. Thus, the implication (12) holds vacuously. The precise and correct description for the state of affairs caused by the cyclic binding is, instead, the negated atom ¬x, whose intuitive reading is “x is not (and never will be) finite.”

We are building an abstract domain for finite-tree dependencies where we are making the deliberate choice of including only information that cannot be withdrawn by forward computations. The reason for this choice is that we want the concrete constraint accumulation process to be paralleled, at the abstract level, by another constraint accumulation process: logical conjunction of Boolean formulas. For this reason, it is important to distinguish between permanent and contingent information. Permanent information, once established for a program point p, maintains its validity in all program points that follow p in any forward computation. Contingent information, instead, does not carry its validity beyond the point where it is established.

An example of contingent information is given by the h component of H × P: having x ∈ h, in the description of some program point, means that x is definitely bound to a finite term at that program point; nothing is claimed about the finiteness of x at other program points and, in fact, unless x is ground, x can still be bound to a non-finite term. However, if at some program point variable x is both finite and ground, then x is permanently finite. In this case we will make sure our Boolean dependency formula entails the positive atom x.

At this stage, we already know something about the abstract domain we are designing. In particular, we have positive and negated atoms, the requirement of describing program predicates of any arity implies that arbitrary conjunctions of these atomic formulas must be allowed and, finally, it is not difficult to observe that the merge-over-all-paths operations [16] will be logical disjunction, so that the domain will have to be closed under this operation. This means that the carrier of our domain must be able to express any Boolean function: Bfun is the carrier.

Definition 12. (γ_{F} : Bfun → ℘(RSubst).) The function hval: RSubst → Bval is defined, for each σ ∈ RSubst and each x ∈ VI, by

hval(σ)(x) = 1 ⟺^{def} x ∈ hvars(σ).

The concretization function γ_{F} : Bfun → ℘(RSubst) is given, for each ϕ ∈ Bfun, by

γ_{F} (ϕ) =^{def} { σ ∈ RSubst | ∀τ ∈ ↓ σ : ϕ(hval(τ)) = 1 }.

Finite-tree dependencies only capture information that cannot be withdrawn by any forward computation.

Proposition 12. Let σ, τ ∈ RSubst and ϕ ∈ Bfun, where σ ∈ γ_{F} (ϕ) and τ ∈ ↓ σ. Then τ ∈ γ_{F} (ϕ).

Proof. By the hypothesis, τ ∈ ↓ σ, so that, for each υ ∈ ↓ τ, υ ∈ ↓ σ. Therefore, as σ ∈ γ_{F} (ϕ), it follows from Definition 12 that, for all υ ∈ ↓ τ, ϕ(hval(υ)) = 1 and hence τ ∈ γ_{F} (ϕ).

As a consequence, every element of the codomain of γ_{F} contains equivalence classes with respect to the RT theory.

Corollary 13. Let σ, τ ∈ RSubst, where σ ∈ γ_{F} (ϕ) and RT ⊢ ∀(σ ↔ τ). Then τ ∈ γ_{F} (ϕ).

By the next lemma, the γ_{F} function is meet-preserving and hence monotonic. This result also implies that the image of Bfun under γ_{F} is Moore-closed. Hence [17], γ_{F} has an adjoint (abstraction) function that is given by

α_{F} (Σ) =^{def} ⋀{ ϕ ∈ Bfun | Σ ⊆ γ_{F} (ϕ) }.

Lemma 14. Let ϕ_{1}, ϕ_{2} ∈ Bfun. Then

γ_{F} (ϕ_{1} ∧ ϕ_{2}) = γ_{F} (ϕ_{1}) ∩ γ_{F} (ϕ_{2}).

Proof.

γ_{F} (ϕ_{1} ∧ ϕ_{2})

= { σ ∈ RSubst | ∀τ ∈ ↓ σ : (ϕ_{1} ∧ ϕ_{2})(hval(τ)) = 1 }

= { σ ∈ RSubst | ∀τ ∈ ↓ σ : ∀i ∈ {1, 2} : ϕ_{i}(hval(τ)) = 1 }

= { σ ∈ RSubst | ∀τ ∈ ↓ σ : ϕ_{1}(hval(τ)) = 1 }

∩ { σ ∈ RSubst | ∀τ ∈ ↓ σ : ϕ_{2}(hval(τ)) = 1 }

= γ_{F} (ϕ_{1}) ∩ γ_{F} (ϕ_{2}).

The next theorem considers most of the operators needed to compute the concrete semantics of a logic program, showing how they can be correctly approximated on the abstract domain Bfun.

Theorem 15. Let Σ, Σ_{1}, Σ_{2} ∈ ℘(RSubst) and ϕ, ϕ_{1}, ϕ_{2} ∈ Bfun, where γ_{F} (ϕ) ⊇ Σ, γ_{F} (ϕ_{1}) ⊇ Σ_{1}, and γ_{F} (ϕ_{2}) ⊇ Σ_{2}. Let also (x ↦ t) ∈ Bind, where {x} ∪ vars(t) ⊆ VI. Then the following hold:

γ_{F} (x ↔ ⋀ vars(t))
⊇ {{x ↦ t}};  (15a)
γ_{F} (¬x) ⊇ {{x ↦ t}}, if x ∈ vars(t);  (15b)
γ_{F} (x) ⊇ \{ σ ∈ RSubst | \begin{matrix}x ∈ gvars(σ) \\ ∩ hvars(σ) \end{matrix} \}; (15c)
γ_{F} (ϕ_{1} ∧ ϕ_{2}) ⊇ { mgs(σ_{1} ∪ σ_{2}) | σ_{1} ∈ Σ_{1}, σ_{2} ∈ Σ_{2} }; (15d)
γ_{F} (ϕ_{1} ∨ ϕ_{2}) ⊇ Σ_{1} ∪ Σ_{2};  (15e)
γ_{F} (∃x . ϕ) ⊇ ∃∃ x . Σ.  (15f)

Proof. Assuming the hypothesis of the theorem, we will prove each relation separately.

(15a). Let σ = {x ↦ t}. Suppose τ ∈ ↓ σ. Then, by Proposition 2, RT ⊢ ∀(τ → σ). It follows from Lemma 6 that rt(x, τ) = rt(t, τ) and thus, by case (8b) of Corollary 8, x ∈ hvars(τ) if and only if vars(t) ⊆ hvars(τ). This is equivalent to (x ↔ ⋀ vars(t))(0[1/ hvars(τ)]) = 1 and, by Definition 12, to (x ↔ ⋀ vars(t))(hval(τ)) = 1. As this holds for all τ ∈ ↓ σ, by Definition 12, σ ∈ γ_{F} (x ↔ ⋀ vars(t)).

(15b). Let σ = {x ↦ t}, where x ∈ vars(t). By Definition 10, we have x ∉ hvars(σ). By case (9a) of Proposition 9, for all τ ∈ ↓ σ, we have hvars(τ) ⊆ hvars(σ). Thus x ∉ hvars(τ) and (¬x)(hval(τ)) = 1. Therefore, by Definition 12, σ ∈ γ_{F} (¬x).

(15c). Let σ ∈ RSubst such that x ∈ gvars(σ) ∩ hvars(σ). By case (9b) of Proposition 9, we have x ∈ hvars(τ) for all τ ∈ ↓ σ. So (x)(hval(τ)) = 1. Therefore, by Definition 12, σ ∈ γ_{F} (x).

(15d). Let σ_{1} ∈ Σ_{1} and σ_{2} ∈ Σ_{2}. Then, by hypothesis σ_{1} ∈ γ_{F} (ϕ_{1}) and σ_{2} ∈ γ_{F} (ϕ_{2}). Let τ ∈ mgs(σ_{1} ∪ σ_{2}). By definition of mgs, RT ⊢ ∀(τ → σ_{1}) and RT ⊢ ∀(τ → σ_{2}). Thus, by Proposition 2, we have τ ∈ ↓ σ_{1} ∩ ↓ σ_{2}. Therefore, by Proposition 12, τ ∈ γ_{F} (ϕ_{1}) ∩ γ_{F} (ϕ_{2}). The result then follows by Lemma 14.

(15e).

γ_{F} (ϕ_{1} ∨ ϕ_{2})

= { σ ∈ RSubst | ∀τ ∈ ↓ σ : (ϕ_{1} ∨ ϕ_{2})(hval(τ)) = 1 }

= { σ ∈ RSubst | ∀τ ∈ ↓ σ : ∃i ∈ {1, 2} . ϕ_{i}(hval(τ)) = 1 }

⊇ { σ ∈ RSubst | ∀τ ∈ ↓ σ : ϕ_{1}(hval(τ)) = 1 }

∪ { σ ∈ RSubst | ∀τ ∈ ↓ σ : ϕ_{2}(hval(τ)) = 1 }

= γ_{F} (ϕ_{1}) ∪ γ_{F} (ϕ_{2}) ⊇ Σ_{1} ∪ Σ_{2}.

(15f). Let σ ∈ Σ and let σ′ ∈ ∃∃ x . {σ}. We will show that σ′ ∈ γ_{F} (∃x . ϕ).

Let τ′ ∈ ↓ σ′. Then there exists σ′_{1} ∈ RSubst such that RT ⊢ ∀(τ′ ↔ (σ′ ∪ σ′_{1})). Let σ_{1} ∈ ∃∃ x . {σ′_{1}} and let

W =^{def} (Vars \ VI) ∪ {x}. Then, by Definition 5, it follows RT ⊢ ∀(∃W . (σ′ ↔ σ)) and RT ⊢ ∀(∃W . (σ′_{1} ↔ σ_{1})). As a consequence

RT ⊢ ∀(∃W . (σ′ ∪ σ′_{1}) ↔ ∃W . (σ ∪ σ_{1})).

Therefore σ ∪ σ_{1} is satisfiable so that, for some τ ∈ RSubst, RT ⊢ ∀(τ ↔ (σ ∪ σ_{1})). Thus RT ⊢ ∀(∃W . τ ↔ ∃W . τ′). By Proposition 10, hvars(τ′) \ W = hvars(τ) \ W so that

(hvars(τ′) ∩ VI) ∪ {x} = (hvars(τ) ∩ VI) ∪ {x}. (14)

Let c =^{def} hval(τ)(x). Then, since τ ∈ ↓ σ and, by hypothesis, σ ∈ γ_{F} (ϕ), we have the following chain of implications:

ϕ(hval(τ)) = 1 [by Defn. 12]
ϕ(hval(τ)[c/x]) = 1 [by Defn. 2]
ϕ(0[1/ hvars(τ) ∩ VI][c/x]) = 1 [by Defn. 12]
ϕ(0[1/(hvars(τ) ∩ VI) ∪ {x}][c/x]) = 1 [by Defn. 2]
ϕ(0[1/(hvars(τ′) ∩ VI) ∪ {x}][c/x]) = 1  [by (14)]
ϕ(0[1/ hvars(τ′) ∩ VI][c/x]) = 1 [by Defn. 2]
ϕ(hval(τ′)[c/x]) = 1 [by Defn. 12]
ϕ[c/x](hval(τ′)) = 1. [by Defn. 3]

From this last relation, since ϕ[c/x] ⊧ ∃x . ϕ, it follows that (∃x . ϕ)(hval(τ′)) = 1. As this holds for all τ′ ∈ ↓ σ′, by Definition 12, σ′ ∈ γ_{F} (∃x . ϕ).

Cases (15a), (15b), and (15d) of Theorem 15 ensure that the following definition of amgu_{F} provides a correct approximation on Bfun of the concrete unification of rational trees.

Definition 13. The function amgu_{F} : Bfun×Bind → Bfun captures the effects of a binding on a finite-tree dependency component. Let ϕ ∈ Bfun and (x ↦ t) ∈ Bind. Then

amgu_{F} (ϕ, x ↦ t) =^{def} \begin{cases}ϕ ∧ (x ↔ ⋀ vars(t)), & if x ∉ vars(t); \\ ϕ ∧ ¬x, & otherwise. \end{cases}

Other semantic operators, such as the consistent renaming of variables, are very simple and, as usual, their approximation does not pose any problem.

The next theorem suggests how finite-tree dependencies can be exploited in order to improve the finiteness information encoded in the h component of the domain H × P.

Theorem 16. Let h ∈ H and ϕ ∈ Bfun. Let also

h′ =^{def} true(ϕ ∧ ⋀ h).

Then

γ_{H}(h) ∩ γ_{F} (ϕ) = γ_{H}(h′) ∩ γ_{F} (ϕ).

Proof. Since h ⊆ h′, by the monotonicity of γ_{H} we have γ_{H}(h) ⊇ γ_{H}(h′), so that we obtain one of the inclusions: γ_{H}(h) ∩ γ_{F} (ϕ) ⊇ γ_{H}(h′) ∩ γ_{F} (ϕ).

In order to establish the other inclusion, we now prove that σ ∈ γ_{H}(h′) assuming σ ∈ γ_{H}(h) ∩ γ_{F} (ϕ). To this end, by Definition 11, it is sufficient to prove that h′ ⊆ hvars(σ).

Let z ∈ h′ and let ψ = (ϕ ∧ ⋀ h), so that, by hypothesis, h′ = true(ψ). Therefore, we have ψ ⊧ z. Consider now ψ′ = (ϕ ∧ ⋀ hvars(σ)). Since σ ∈ γ_{H}(h), by Definition 11 we have h ⊆ hvars(σ), so that ψ′ ⊧ ψ and thus ψ′ ⊧ z.

Since σ ∈ γ_{F} (ϕ), by Definition 12 we have ϕ(hval(σ)) = 1. Also note that (⋀ hvars(σ))(hval(σ)) = 1. From these, by the definition of conjunction for Boolean formulas, we obtain ψ′(hval(σ)) = 1. Thus we can observe that

ψ′(hval(σ)) = 1 ⟺ (ψ′ ∧ z)(hval(σ)) = 1
⟹ z ∈ hvars(σ).

Example 2. Consider the following program, where it is assumed that the only “external” query is ?- r(X, Y).

  p(X, Y) :- X = f(Y,  ).
  q(X, Y) :- X = f( , Y).
  r(X, Y) :- p(X, Y), q(X, Y), acyclic term(X).

Consider the call at the predicate p/2 in the body of the clause defining r/2. The predicate p/2 is called with variables X and Y both unbound. When computing on the abstract domain H × P, we obtain a finiteness description h_{p} ∈ H such that h_{p} = {x, y}, expressing the fact that both X and Y are bound to finite terms. When computing finite-tree dependencies on Bfun, the abstract semantics of p/2 is expressed by the Boolean formula ϕ_{p} = x → y (Y is finite if X is so).

Considering now the call to the predicate q/2, we note that, since variable X is already bound to a non-variable term sharing with Y, all the finiteness information encoded by H will be lost (i.e., h_{q} = ∅). So, both X and Y are detected as possibly cyclic. However, the finite-tree dependency information is preserved, because ϕ_{q} = (x → y) ∧ (x → y) = x → y.

Finally, consider the effect, on the semantics of r/2, of the abstract evaluation of the built-in acyclic_term(X). On the H × P domain we can only infer that variable X cannot be bound to an infinite term, while Y will be still considered as possibly cyclic, so that h_{r} = {x}. On the domain Bfun we can just confirm that the finite-tree dependency computed so far still holds, so that ϕ_{r} = x → y (no stronger finite-tree dependency can be inferred, since the finiteness of X is only contingent). Thus, by applying the result of Theorem 16, we can recover the finiteness of variable y:

h′_{r} = true(ϕ_{r} ∧ ⋀ h_{r}) = true((x → y) ∧ x) = {x, y}.

A safe strategy to exploit finite-tree dependencies in the analysis is to apply the reduction step of Theorem 16 immediately after any application of any abstract operator. For instance, this is how predicates like acyclic_term/1 are handled: the variables of the argument are added to the H component and this is followed by reduction. However, the approach of always performing reduction is unnecessarily inefficient since it is possible to identify cases when Theorem 16 cannot lead to a precision improvement.

Theorem 17. Let x ∈ VI, h, h′ ∈ H and ϕ, ϕ′ ∈ Bfun, where h ⊇ true(ϕ ∧ ⋀ h) and h′ ⊇ true(ϕ′ ∧ ⋀ h′). Let also

h_{1} =^{def} h ∩ h′,  h_{2} =^{def} h ∪ {x},
ϕ_{1} =^{def} ϕ ∨ ϕ′,  ϕ_{2} =^{def} ∃x . ϕ.

Then, for i = 1, 2,

h_{i} ⊇ true(ϕ_{i} ∧ ⋀ h_{i}).

Proof. We assume the hypotheses and prove each statement in turn. For the case where i = 1 we have:

h_{1} =^{def} h ∩ h′

⊇ true(ϕ ∧ ⋀ h) ∩ true(ϕ′ ∧ ⋀ h′)

⊇ true(ϕ ∧ ⋀(h ∩ h′)) ∩ true(ϕ′ ∧ ⋀(h ∩ h′))

= true(ϕ ∧ ⋀(h ∩ h′) ∨ ϕ′ ∧ ⋀(h ∩ h′))

= true((ϕ ∨ ϕ′) ∧ ⋀(h ∩ h′))

= true(ϕ_{1} ∧ ⋀ h_{1}).

For the case where i = 2 we have:

h_{2} =^{def} h ∪ {x}

⊇ true(ϕ ∧ ⋀ h) ∪ {x}

⊇ true((∃x . ϕ) ∧ ⋀ h) ∪ {x}

= true((∃x . ϕ) ∧ ⋀(h ∪ {x}))

= true(ϕ_{2} ∧ ⋀ h_{2}).

Information encoded in H ×P and Bfun is not completely orthogonal and the following result provides a kind of consistency check.

Theorem 18. Let h ∈ H and ϕ ∈ Bfun. Then

γ_{H}(h) ∩ γ_{F} (ϕ) ≠ ∅ ⟹ h ∩ false(ϕ) = ∅.

Proof. Suppose that there exists σ ∈ γ_{H}(h) ∩ γ_{F} (ϕ). By Definition 12, since σ ∈ ↓ σ, we have ϕ(hval(σ)) = 1; therefore, we also have

hvars(σ) ∩ false(ϕ) = ∅;

by Definition 11, we have h ⊆ hvars(σ), so that we can conclude h ∩ false(ϕ) = ∅.

Note however that, provided the abstract operators computing on the two components are correct, the computed descriptions will always be mutually consistent, unless ϕ = ⊥.

5. GROUNDNESS DEPENDENCIES

Since information about the groundness of variables is crucial for many applications, it is very natural to consider a static analysis domain including both a finite-tree component and a groundness component. As a matter of fact, any reasonably precise implementation of the parameter component P of the abstract domain specified in [3] will include some kind of groundness information.^{7} In this section we will highlight similarities, differences and connections relating the domain Bfun for finite-tree dependencies to the wellknown abstract domain Pos for groundness dependencies. Note however that many of the established results hold also when considering a combination of Bfun with the groundness domain Def [1].

Definition 14. (γ_{G}: Pos → ℘(RSubst).) The auxiliary function gval: RSubst → Bval is defined as follows, for each σ ∈ RSubst and each x ∈ VI:

gval(σ)(x) = 1 ⟺^{def} x ∈ gvars(σ).

The concretization function γ_{G}: Pos → ℘(RSubst) is given, for each ψ ∈ Pos, by

γ_{G}(ψ) =^{def} { σ ∈ RSubst | ∀τ ∈ ↓ σ : ψ(gval(τ)) = 1 }.

As was the case for finite-tree dependencies, groundness dependencies only capture permanent information, therefore preserving the equivalence relation induced by RT . Moreover, the γ_{G} function is meet-preserving.

Proposition 19. Let σ, τ ∈ RSubst and ψ ∈ Pos, where σ ∈ γ_{G}(ψ) and τ ∈ ↓ σ. Then τ ∈ γ_{G}(ψ).

Proof. By the hypothesis, τ ∈ ↓ σ, so that, for each υ ∈ ↓ τ, υ ∈ ↓ σ. Therefore, as σ ∈ γ_{G}(ϕ), it follows from Definition 14 that, for all υ ∈ ↓ τ, ψ(gval(υ)) = 1 and hence τ ∈ γ_{G}(ϕ).

Corollary 20. Let σ, τ ∈ RSubst and ψ ∈ Pos, where σ ∈ γ_{G}(ψ) and RT ⊢ ∀(σ ↔ τ). Then τ ∈ γ_{G}(ψ).

Lemma 21. Let ψ_{1}, ψ_{2} ∈ Pos. Then

γ_{G}(ψ_{1} ∧ ψ_{2}) = γ_{G}(ψ_{1}) ∩ γ_{G}(ψ_{2}).

7One could define P so as it explicitly contains the abstract domain Pos. Even when this is not the case, it should be noted that, as soon as the parameter P includes the setsharing domain of Jacobs and Langen [28], then it will subsume the groundness information captured by the domain Def [9, 14].

Proof.

γ_{G}(ψ_{1} ∧ ψ_{2})

= { σ ∈ RSubst | ∀τ ∈ ↓ σ : (ψ_{1} ∧ ψ_{2})(gval(τ)) = 1 }

= \{ σ ∈ RSubst | \begin{matrix}∀τ ∈ ↓ σ : ∀i ∈ \{1, 2\} : \\ ψ_{i}(gval(τ)) = 1 \end{matrix} \}

= { σ ∈ RSubst | ∀τ ∈ ↓ σ : ψ_{1}(gval(τ)) = 1 }

∩ { σ ∈ RSubst | ∀τ ∈ ↓ σ : ψ_{2}(gval(τ)) = 1 }

= γ_{G}(ψ_{1}) ∩ γ_{G}(ψ_{2}).

The following is a simple variant of the standard abstract unification operator defined for groundness analysis over finite-tree domains: the only difference concerns the case of cyclic bindings [2].

Definition 15. The function amgu_{G}: Pos × Bind → Pos captures the effects of a binding on a groundness dependency component. Let ψ ∈ Pos and (x ↦ t) ∈ Bind. Then

amgu_{G}(ψ, x ↦ t) =^{def} ψ ∧ (x ↔ ⋀(vars(t) \ {x})).

Since non-ground terms can be made cyclic by instantiating their variables, those terms detected as definitely finite on Bfun are also definitely ground.

Lemma 22. Let x ∈ VI. Then γ_{F} (x) ⊆ γ_{G}(x).

Proof. Suppose that σ ∈ γ_{F} (x). Then, by Definition 12, (x)(hval(τ)) = 1 for all τ ∈ ↓ σ, so that x ∈ hvars(τ); in particular, x ∈ hvars(σ). We prove x ∈ gvars(σ) by contradiction. That is, we show that if x ∈ hvars(σ) \ gvars(σ), then there exists τ ∈ ↓ σ for which x ∉ hvars(τ).

Suppose therefore that x ∈ hvars(σ) \ gvars(σ). Then, by Proposition 7, rt(x, σ) ∈ HTerms \ GTerms. Hence, by Proposition 1, there exists i ∈ ℕ such that rt(x, σ) = xσ^{i} and there exists y ∈ vars(xσ^{i})\dom(σ). As we assumed that Sig contains a function symbol of non-zero arity, there exists t ∈ HTerms \ {y} for which {y} = vars(t). It follows that σ′ = {y ↦ t} ∈ RSubst and, by Definition 10, y ∉ hvars(σ′). Since y ∉ dom(σ), by Lemma 3, τ = σ ∪ σ′ ∈ RSubst. Since τ ∈ ↓ σ′ then, by case (9a) of Proposition 9, we have y ∉ hvars(τ).

By Lemma 4, RT ⊢ ∀(σ → (x = xσ^{i})). Thus, since we also have τ ∈ ↓ σ, we obtain RT ⊢ ∀(τ → (x = xσ^{i})). By applying Lemma 6, we have rt(x, τ) = rt(xσ^{i}, τ) so that, by case (8b) of Corollary 8, we obtain x ∈ hvars(τ) if and only if vars(xσ^{i}) ⊆ hvars(τ). However, as observed before, y ∈ vars(xσ^{i}) \ hvars(τ), so that we also have x ∉ hvars(τ).

Therefore x ∈ gvars(σ) ∩ hvars(σ) and, by case (9b) of Proposition 9, for all τ ∈ ↓ σ, x ∈ gvars(τ) ∩ hvars(τ). As a consequence, for all τ ∈ ↓ σ, (x)(gval(τ)) = 1, so that, by Definition 14, we can conclude that σ ∈ γ_{G}(x).

The following theorem specifies a reduction process that can improve the precision of the groundness dependencies (Pos) component by exploiting the information available in the finite-tree dependencies (Bfun) component.

Theorem 23. Let ϕ ∈ Bfun and ψ ∈ Pos. Let ν ∈ Pos be defined as ν = ⋀ true(ϕ). Then

γ_{F} (ϕ) ∩ γ_{G}(ψ) = γ_{F} (ϕ) ∩ γ_{G}(ψ ∧ ν).

Proof. Since ψ ∧ ν ⊧ ψ, the inclusion

γ_{F} (ϕ) ∩ γ_{G}(ψ) ⊇ γ_{F} (ϕ) ∩ γ_{G}(ψ ∧ ν)

follows by the monotonicity of γ_{G}. To prove the inclusion

γ_{F} (ϕ) ∩ γ_{G}(ψ) ⊆ γ_{F} (ϕ) ∩ γ_{G}(ψ ∧ ν)

we will show that γ_{F} (ϕ) ⊆ γ_{G}(ν). The thesis will follow as, by Lemma 21, γ_{G}(ψ ∧ ν) = γ_{G}(ψ) ∩ γ_{G}(ν). We have

γ_{F} (ϕ) ⊆ γ_{F} (ν)  [since ϕ ⊧ ν]
= ⋂{ γ_{F} (x) | x ∈ true(ϕ) } [by Lemma 14]
⊆ ⋂{ γ_{G}(x) | x ∈ true(ϕ) } [by Lemma 22]
= γ_{G}(ν).  [by Lemma 21]

The following two examples shows that, when computing on rational trees, finite-tree dependencies may provide groundness information that is not captured by the usual approaches.

Example 3. Consider the following program:

                                                                  p(a, a).
                                                                  p(X, Y) :- X = f(X,  ).
                                                                  q(X, Y) :- p(X, Y), X = a.

Consider first the predicate p/2. Concerning finite-tree dependencies, the abstract semantics of p/2 is expressed by the Boolean formula ϕ_{p} = x → y (y is finite if x is so). In contrast, the Pos-groundness abstract semantics of p/2 is a plain “don’t know”: the Boolean formula ψ_{p} = ⊤. In fact, the groundness of X and Y can be completely decided by the call-pattern of p/2.

Consider now the predicate q/2. The finiteness semantics of q/2 is ϕ_{q} = (x → y) ∧ x = x ∧ y, whereas the Pos formula expressing groundness dependencies is ψ_{q} = ⊤ ∧ x = x. By applying the reduction process of Theorem 23, we obtain

ψ′_{q} = ψ_{q} ∧ ⋀ true(ϕ_{q}) = x ∧ y,

therefore recovering the groundness of variable y.

Example 4. Consider the program:

                                                                p(a, Y).
                                                                p(X, a).
                                                                q(X, Y) :- p(X, Y), X = f(X, Z).

The abstract semantics of predicate p/2, for both finite-tree and groundness dependencies, is ϕ_{p} = ψ_{p} = x ∨ y.

Consider now the predicate q/2. Concerning finite-tree dependencies, the abstract semantics of q/2 is expressed by the Boolean formula ϕ_{q} = (x ∨ y) ∧ ¬x = ¬x ∧ y (x is definitely cyclic and y is definitely finite). On the domain Pos, by applying Definition 15, we compute

ψ_{q} = ∃z . ((x ∨ y) ∧ (x ↔ z))
= x ∨ y.

Thus we can apply Theorem 23 and improve the groundness dependencies description by computing

ψ′_{q} = ψ_{q} ∧ ⋀ true(ϕ_{q}) = y.

Since groundness information, besides being useful in itself, also has the potential of improving the precision of many other analyses, such as sharing information [6, 9], by applying the reduction step of Theorem 23 we can indeed trigger some reduction processes affecting the precision of other components. Theorem 23 can also be exploited in the application of a widening operator on the groundness dependencies component. However, as was the case for Theorem 16, there are cases when Theorem 23 cannot provide a precision gain.

Theorem 24. Let ϕ, ϕ′ ∈ Bfun and ψ, ψ′ ∈ Pos, where ψ ⊧ ⋀ true(ϕ) and ψ′ ⊧ ⋀ true(ϕ′). Let also

ϕ_{1} =^{def} ϕ ∨ ϕ′,  ϕ_{2} =^{def} ∃x . ϕ,
ψ_{1} =^{def} ψ ∨ ψ′,  ψ_{2} =^{def} ∃x . ψ.

Then, for i = 1, 2,

ψ_{i} ⊧ ⋀ true(ϕ_{i}).

Proof. Let us assume the hypotheses hold and prove each statement in turn. For the case where i = 1 we have:

ψ_{1} =^{def} ψ ∨ ψ′

⊧ ⋀ true(ϕ) ∨ ⋀ true(ϕ′)

⊧ ⋀ true(ϕ ∨ ϕ′)

=^{def} ⋀ true(ϕ_{1}).

Since by hypothesis we have that ψ ⊧ ⋀ true(ϕ) and existential quantification is a monotonic operation, for the case where i = 2 we have:

ψ_{2} =^{def} ∃x . ψ

⊧ ∃x . ⋀ true(ϕ)

= ⋀(true(ϕ) \ {x})

= ⋀ true(∃x . ϕ)

=^{def} ⋀ true(ϕ_{2}).

Another interesting question is whether or not we can define a reduction process working the other way round, i.e., trying to improve the finite-tree dependencies component based on the information encoded in the groundness dependencies component. The following theorem shows that this is theoretically possible, provided the information of the finiteness component H is also available.

Theorem 25. Let h ∈ H, ϕ ∈ Bfun and ψ ∈ Pos. Let ν ∈ Bfun be defined as ν = (∃VI \ h . ψ). Then

γ_{H}(h) ∩ γ_{F} (ϕ) ∩ γ_{G}(ψ) = γ_{H}(h) ∩ γ_{F} (ϕ ∧ ν) ∩ γ_{G}(ψ).

Proof. Since ϕ ∧ ν ⊧ ϕ, the inclusion

γ_{H}(h) ∩ γ_{F} (ϕ) ∩ γ_{G}(ψ) ⊇ γ_{H}(h) ∩ γ_{F} (ϕ ∧ ν) ∩ γ_{G}(ψ)

follows by the monotonicity of γ_{G}.

We now prove the reverse inclusion. Let us suppose that σ ∈ γ_{H}(h) ∩ γ_{F} (ϕ) ∩ γ_{G}(ψ). By Lemma 14 we have that γ_{F} (ϕ ∧ ν) = γ_{F} (ϕ) ∩ γ_{F} (ν). Therefore it is enough to show that σ ∈ γ_{F} (ν). By hypothesis, ν = ∃VI \ h . ψ. Moreover, by Definition 11, h ⊆ hvars(σ). Thus, to prove the result, we will show, by contradiction, that σ ∈ γ_{F} (∃VI\hvars(σ) . ψ).

Suppose therefore that σ ∉ γ_{F} (∃VI \ hvars(σ) . ψ). Then there exists τ ∈ ↓ σ such that

(∃VI \ hvars(σ) . ψ)(hval(τ)) = 0.  (15)

Take t ∈ GTerms ∩ HTerms and let

υ =^{def} { y ↦ t | y ∈ vars(σ) ∩ (hvars(τ) \ dom(σ)) }. (16)

By Lemma 3, τ′ =^{def} σ ∪ υ ∈ RSubst is satisfiable in RT .

Let z be any variable in hvars(σ). By case (7b) of Proposition 7, rt(z, σ) ∈ HTerms. By Proposition 1, there exists i ∈ ℕ such that rt(z, σ) = zσ^{i} and vars(zσ^{i}) ∩ dom(σ) = ∅. Therefore, by Definition 10, vars(zσ^{i}) ⊆ hvars(σ). Thus, we have

vars(zσ^{i}) ⊆ hvars(σ) \ dom(σ).  (17)

By Lemma 4, as τ ∈ ↓ σ, RT ⊢ ∀(τ → (z = zσ^{i})). By Lemma 6, we have rt(z, τ) = rt(zσ^{i}, τ) so that, by case (8b) of Corollary 8,

z ∈ hvars(τ) ⟺ vars(zσ^{i}) ⊆ hvars(τ).  (18)

We now show that

hvars(τ) = hvars(σ) ∩ gvars(τ′).  (19)

Since τ ∈ ↓ σ, it follows from case (9a) of Proposition 9 that hvars(τ) ⊆ hvars(σ). Thus, as z ∈ hvars(σ), either z ∈ hvars(τ) or z ∈ hvars(σ) \ hvars(τ). We consider these cases separately.

First, assume that z ∈ hvars(τ). Then, by (18), we have vars(zσ^{i}) ⊆ hvars(τ). Also, by case (9a) of Proposition 9, we have z ∈ hvars(σ), so that we can apply (17) to derive vars(zσ^{i}) ∩ dom(σ) = ∅. Therefore, vars(zσ^{i}) ⊆ dom(υ) and, by Definitions 8 and 10, vars(zσ^{i}) ⊆ gvars(υ)∩hvars(υ). Since τ′ ∈ ↓ υ, by case (9b) of Proposition 9, we have vars(zσ^{i}) ⊆ gvars(τ′) ∩ hvars(τ′). Thus, by Corollary 8, rt(zσ^{i}, τ′) ∈ GTerms ∩ HTerms. Now τ′ ∈ ↓ σ so that, by Lemma 4, RT ⊢ ∀(τ′ → (z = zσ^{i})). Thus, by Lemma 6, rt(zσ^{i}, τ′) = rt(z, τ′) ∈ GTerms∩HTerms so that, by Proposition 7, z ∈ hvars(τ′) ∩ gvars(τ′). Hence, by case (9a) of Proposition 9, we can conclude z ∈ hvars(σ) ∩ gvars(τ′). Thus hvars(τ) ⊆ hvars(σ) ∩ gvars(τ′).

Secondly, we assume that z ∈ hvars(σ) \ hvars(τ). Since z ∉ hvars(τ), by (18), there exists y ∈ vars(zσ^{i}) \ hvars(τ). Also, since z ∈ hvars(σ), by (17), y ∈ hvars(σ) \ dom(σ) so that, by Definition 8, we have y ∉ gvars(σ). By (16), since y ∉ dom(σ) ∪ hvars(τ), we have y ∉ dom(υ) so that y ∉ gvars(τ′). Thus, by case (8a) of Corollary 8, we have rt(zσ^{i}, τ′) ∉ GTerms. Also, as RT ⊢ ∀(τ′ → (z = zσ^{i})), by Lemma 6 we have rt(zσ^{i}, τ′) = rt(z, τ′) ∉ GTerms and therefore, by case (7a) of Proposition 7, z ∉ gvars(τ′). Thus hvars(τ) ⊇ hvars(σ) ∩ gvars(τ′).

It follows from (15) and (19) that,

(∃VI \ hvars(σ) . ψ)(gval(τ′)) = 0.  (20)

It also holds by hypothesis that σ ∈ γ_{G}(ψ), so that, since τ′ ∈ ↓ σ, by Definition 14 we have ψ(gval(τ′)) = 1. Therefore, as ψ ⊧ ∃VI \ hvars(σ) . ψ,

(∃VI \ hvars(σ) . ψ)(gval(τ′)) = 1,

which contradicts (20).

As was the case for Theorems 16 and 23, when abstractly evaluating the existential quantification and the merge-over-all-paths operations, the application of the reduction process of Theorem 25 is unnecessary.

Theorem 26. Let h, h′ ∈ H, ϕ, ϕ′ ∈ Bfun, ψ, ψ′ ∈ Pos, where ϕ ⊧ (∃VI \ h . ψ) and ϕ′ ⊧ (∃VI \ h′ . ψ′). Let also

h_{1} =^{def} h ∩ h′,  h_{2} =^{def} h ∪ {x},
ϕ_{1} =^{def} ϕ ∨ ϕ′,  ϕ_{2} =^{def} ∃x . ϕ,
ψ_{1} =^{def} ψ ∨ ψ′,  ψ_{2} =^{def} ∃x . ψ.

Then, for i = 1, 2,

ϕ_{i} ⊧ (∃VI \ h_{i} . ψ_{i}).

Proof. Let us assume the hypotheses. For the case where i = 1 we have:

ϕ_{1} =^{def} ϕ ∨ ϕ′

⊧ (∃VI \ h . ψ) ∨ (∃VI \ h′ . ψ′)

⊧ (∃VI \ (h ∩ h′) . ψ)∨(∃VI \ (h ∩ h′) . ψ′)

= ∃VI \ (h ∩ h′) . ψ ∨ ψ′

=^{def} ∃VI \ h_{1} . ψ_{1}.

Since by hypothesis we have that ϕ ⊧ ∃VI \ h . ψ and existential quantification is a monotonic operation, for the case where i = 2 we have:

ϕ_{2} =^{def} ∃x . ϕ

⊧ ∃x . ∃VI \ h . ψ = ∃VI \ h . ∃x . ψ

= ∃VI \ (h ∪ {x}) . ∃x . ψ

=^{def} ∃VI \ h_{2} . ψ_{2}.

We conjecture that Theorem 26 can be strengthened so that it also applies to the case of abstract unification. However, when precision is lost due to the use of a widening operator on the Bfun component, some of this could be recovered by means of the reduction process given by Theorem 25.

6. CONCLUSION

Several modern logic-based languages offer a computation domain based on rational trees. On the one hand, the use of such trees is encouraged by the possibility of using efficient and correct unification algorithms and by an increase in expressivity. On the other hand, these gains are countered by the extra problems rational trees bring with themselves and that can be summarized as follows: several built-ins, library predicates, program analysis and manipulation techniques are only well-defined for program fragments working with finite trees. For these reasons, applications exploiting rational trees tend to do so in a very controlled way, that is, most program variables can only be bound to finite terms. If we are able to detect with enough precision the program variables that may be bound to infinite terms, then we can take advantage of rational trees yet minimizing the impact of their disadvantages.

In a companion paper [3] we have proposed an initial solution to the problem, where the composite abstract domain H × P allows to track, with significant precision, the creation and propagation of infinite terms. Even though this information is crucial to any finite-tree analysis, propagating the guarantees of finiteness that come from several built-ins (including those that are explicitly provided to test termfiniteness) is also important. This is what motivates the work described in this paper, where we have introduced a domain of Boolean functions that is meant to be coupled to H × P, supplementing its expressive power.

In this paper we have studied all the theoretical issues concerning this Boolean domain for finite-tree dependencies. Since this domain has many similarities with the domain Pos used for groundness analysis, we have investigated how these two domains relate to each other and what are the possibilities when both of them are included in the “global” domain of analysis. The work described here and in [3] allowed to complete the preparation of the theoretical stage that is required before proceeding to the implementation of the overall finite-tree analysis domain. The implementation of the domains is now in progress. Concerning the Bfun component things are quite easy, since all the techniques described in [5] (and almost all the code, including the widenings) can be reused unchanged, obtaining, we believe, comparable efficiency results.

7. REFERENCES

[1] T. Armstrong, K. Marriott, P. Schachte, and H. Søndergaard. Two classes of Boolean functions for dependency analysis. Science of Computer Programming, 31(1):3–45, 1998.

[2] R. Bagnara. Data-Flow Analysis for Constraint Logic-Based Languages. PhD thesis, Dipartimento di Informatica, Università di Pisa, Pisa, Italy, 1997. Printed as Report TD-1/97.

[3] R. Bagnara, R. Gori, P. M. Hill, and E. Zaffanella. Finite-tree analysis for constraint logic-based languages. Quaderno 251, Dipartimento di Matematica, Università di Parma, 2001. Available at

    http://www.cs.unipr.it/~bagnara/.

[4] R. Bagnara, P. M. Hill, and E. Zaffanella. Efficient structural information analysis for real CLP languages. In M. Parigot and A. Voronkov, editors, Proc. of the 7th International Conference on Logic for Programming and Automated Reasoning (LPAR 2000), volume 1955 of Lecture Notes in Computer Science, pages 189–206, Reunion Island, France, 2000. Springer-Verlag, Berlin.

[5] R. Bagnara and P. Schachte. Factorizing equivalent variable pairs in ROBDD-based implementations of Pos. In A. M. Haeberer, editor, Proc. of the “Seventh International Conference on Algebraic Methodology and Software Technology (AMAST’98)”, volume 1548 of Lecture Notes in Computer Science, pages 471–485, Amazonia, Brazil, 1999. Springer-Verlag, Berlin.

[6] R. Bagnara, E. Zaffanella, and P. M. Hill. Enhanced sharing analysis techniques: A comprehensive evaluation. In M. Gabbrielli and F. Pfenning, editors, Proc. of the 2nd International ACM SIGPLAN Conference on Principles and Practice of Declarative Programming, pages 103–114, Montreal, Canada, 2000. Association for Computing Machinery.

[7] J. A. Campbell, editor. Implementations of Prolog. Ellis Horwood/Halsted Press/Wiley, 1984.

[8] B. Carpenter. The Logic of Typed Feature Structures with Applications to Unification-based Grammars, Logic Programming and Constraint Resolution, volume 32 of Cambridge Tracts in Theoretical Computer Science. CUP, New York, 1992.

[9] M. Codish, H. Søndergaard, and P. J. Stuckey. Sharing and groundness dependencies in logic programs. ACM Transactions on Programming Languages and Systems, 21(5):948–976, 1999.

[10] A. Colmerauer. Prolog and infinite trees. In K. L. Clark and S. Å. Tärnlund, editors, Logic Programming, APIC Studies in Data Processing, volume 16, pages 231–251. Ac. Press, New York, 1982.

[11] A. Colmerauer. Equations and inequations on finite and infinite trees. In Proc. of the International Conference on Fifth Generation Computer Systems (FGCS’84), pages 85–99, Tokyo, Japan, 1984. ICOT.

[12] A. Colmerauer. An introduction to Prolog-III. Communications of the ACM, 33(7):69–90, 1990.

[13] A. Cortesi, G. Filé, and W. Winsborough. Prop revisited: Propositional formula as abstract domain for groundness analysis. In Proceedings, Sixth Annual IEEE Symposium on Logic in Computer Science, pages 322–327, Amsterdam, The Netherlands, 1991. IEEE Computer Society Press.

[14] A. Cortesi, G. Filé, and W. Winsborough. The quotient of an abstract interpretation for comparing static analyses. Theoretical Computer Science, 202(1&2):163–192, 1998.

[15] A. Cortesi, B. Le Charlier, and P. Van Hentenryck. Combinations of abstract domains for logic programming: Open product and generic pattern construction. Science of Computer Programming, 38(1–3), 2000.

[16] P. Cousot and R. Cousot. Abstract interpretation: A unified lattice model for static analysis of programs by construction or approximation of fixpoints. In Proc. of the Fourth Annual ACM Symposium on Principles of Programming Languages, pages 238–252, 1977.

[17] P. Cousot and R. Cousot. Systematic design of program analysis frameworks. In Proc. of the Sixth Annual ACM Symposium on Principles of Programming Languages, pages 269–282, 1979.

[18] P. Cousot and R. Cousot. Abstract interpretation and applications to logic programs. Journal of Logic Programming, 13(2&3):103–179, 1992.

[19] P. Cousot and R. Cousot. Abstract interpretation frameworks. Journal of Logic and Computation, 2(4):511–547, 1992.

[20] P. W. Dart. On derived dependencies and connected databases. Journal of Logic Programming, 11(1&2):163–188, 1991.

[21] P. R. Eggert and K. P. Chow. Logic programming, graphics and infinite terms. Technical Report UCSB DoCS TR 83-02, Department of Computer Science, University of California at Santa Barbara, 1983.

[22] G. Erbach. ProFIT: Prolog with Features, Inheritance and Templates. In Proc. of the 7th Conference of the European Chapter of the Association for Computational Linguistics, pages 180–187, Dublin, Ireland, 1995.

[23] M. Filgueiras. A Prolog interpreter working with infinite terms. In Campbell [7], pages 250–258.

[24] F. Giannesini and J. Cohen. Parser generation and grammar manipulation using Prolog’s infinite trees. Journal of Logic Programming, 3:253–265, 1984.

[25] S. Haridi and D. Sahlin. Efficient implementation of unification of cyclic structures. In Campbell [7], pages 234–249.

[26] P. M. Hill, R. Bagnara, and E. Zaffanella. Soundness, idempotence and commutativity of set-sharing. Theory and Practice of Logic Programming, 2001. To appear.

                                                        Available at http://arXiv.org/abs/cs.PL/0102030.

[27] B. Intrigila and M. Venturini Zilli. A remark on infinite matching vs infinite unification. Journal of Symbolic Computation, 21(3):2289–2292, 1996.

[28] D. Jacobs and A. Langen. Static analysis of logic programs for independent AND parallelism. Journal of Logic Programming, 13(2&3):291–314, 1992.

[29] J. Jaffar, J-L. Lassez, and M. J. Maher. Prolog-II as an instance of the logic programming scheme. In M. Wirsing, editor, Formal Descriptions of Programming Concepts III, pages 275–299. North-Holland, 1987.

[30] T. Keisu. Tree Constraints. PhD thesis, The Royal Institute of Technology, Stockholm, Sweden, May 1994. SICS Dissertation Series: SICS/D–16–SE.

[31] A. King. Pair-sharing over rational trees. Journal of Logic Programming, 46(1–2):139–155, 2000.

[32] M. J. Maher. Complete axiomatizations of the algebras of finite, rational and infinite trees. In Proceedings, Third Annual Symposium on Logic in Computer Science, pages 348–357, Edinburgh, Scotland, 1988. IEEE Computer Society.

[33] K. Marriott and H. Søndergaard. Notes for a tutorial on abstract interpretation of logic programs. North American Conference on Logic Programming, Cleveland, Ohio, USA, 1989.

[34] K. Marriott and H. Søndergaard. Precise and efficient groundness analysis for logic programs. ACM Letters on Programming Languages and Systems, 2(1–4):181–196, 1993.

[35] K. Mukai. Constraint Logic Programming and the Unification of Information. PhD thesis, Department of Computer Science, Faculty of Engineering, Tokio Institute of Technology, 1991.

[36] C. Pollard and I. A. Sag. Head-Driven Phrase Structure Grammar. University of Chicago Press, Chicago, 1994.

[37] E. Schröder. Der Operationskreis des Logikkalkuls. B. G. Teubner, Leibzig, 1877.

[38] Gert Smolka and Ralf Treinen. Records for logic programming. Journal of Logic Programming, 18(3):229–258, 1994.

[39] H. Søndergaard. An application of abstract interpretation of logic programs: Occur check reduction. In B. Robinet and R. Wilhelm, editors, Proc. of the 1986 European Symposium on Programming, volume 213 of Lecture Notes in Computer Science, pages 327–338. Springer-Verlag, Berlin, 1986.

[40] Swedish Institute of Computer Science, Programming Systems Group. SICStus Prolog User’s Manual, release 3 #0 edition, 1995.