Logical approximation for program analysis

The abstract interpretation of programs relates the exact semantics of a programming language to an approximate semantics that can be eﬀectively computed. We show that, by specifying operational semantics in a speciﬁcation framework based on bottom-up logic programming in ordered logic – a technique we call substructural operational semantics (SSOS) – manifestly sound program approximations can be derived by simple and intuitive transformations and approximations of the logic program. As examples, we describe how to derive control ﬂow and alias analyses from the substructural operational semantics of the relevant languages. logic control stacks. Abstract machine speciﬁcations of programming language semantics are traditionally speciﬁed with states of the form ( K B E ), representing an expression E evaluating on the control stack K and ( K C V ), representing a value V being returned to the stack. In substructural operational semantics, as in the push-down automaton, we represent the stack K not as a single syntactic object but as a sequence of atomic propositions comp ( F ), each of which contain a single stack frame.

the behavior of a single-state push-down automaton for checking that a string has matching brackets by using two rewriting rules: The distinguishing feature of these rewriting rules is that they are local -they do not mention the entire stack or the entire string, just the fragment of the beginning of the string or the top of the stack relevant to the given rule. Execution of the PDA on a particular string of tokens then consists of (1) appending the token hd to the beginning of the string, (2) repeatedly performing rewritings until no more rewrites are possible, and (3)  Because our goal is to use a framework that is both simple and logically-motivated, we turn to ordered logic (originally presented by Lambek [15]), a substructural logic with an intrinsic notion of order. The rewriting rules we considered before can be expressed as propositions in ordered logic, where the tokens hd, [, and ] are all treated as atomic propositions. The symbol • (pronounced "fuse") is the binary connective for ordered conjunction (i.e. concatenation) and has lower precedence than , a binary connective for ordered implication.
This framework of ordered logical specifications is quite powerful; the above example only uses the propositional fragment of ordered logic. If we consider a first-order term language where terms are drawn from the simply-typed lambda calculus (allowing us to use higher-order abstract syntax [24]) we can use ordered logic as a framework for the specification of substructural operational semantics, a synthesis of structural operational semantics, abstract machines, and logical specifications in which machine states are represented by a series of ordered atomic propositions.
One especially distinguishing feature of substructural operational semantics in ordered logic is the treatment of control stacks. Abstract machine specifications of programming language semantics are traditionally specified with states of the form (K E), representing an expression E evaluating on the control stack K, and (K V ), representing a value V being returned to the stack. In substructural operational semantics, as in the push-down automaton, we represent the stack K not as a single syntactic object but as a sequence of atomic propositions comp(F ), each of which contain a single stack frame.
We will give the example of a call-by-value operational semantics for the lambda calculus. The evaluation of a lambda expression, which we write in higher order abstract syntax as lam(λx.E 0 x), is simple: the expression is already a value, so we return it. eval(lam(λx.E 0 x)) retn(lam(λx.E 0 x)) (1) The evaluation of an application app E 1 E 2 requires us to generate a new stack frame (app 1 E 2 ) containing the function argument while we evaluate E 1 to a value.
When a value is returned to a waiting app 1 frame, we switch to evaluating the function argument while storing the returned value on the stack.
Finally, when an evaluated function argument is returned to a waiting app 2 frame, we substitute the value into the body of the lambda expression and evaluate the result.
As usual in higher-order abstract syntax representations, substitution is performed by application.
These four rules constitute a substructural operational semantics specification of the call-by-value lambda calculus; an example of the evaluation of an expression to a value under this specification is given in Figure 1. SSOS specifications in ordered logic are conceptually simple, notationally clean, and provide a modular basis for the specification of many stateful and concurrent programming language features, as discussed in [26].
These two steps, the transformation from ordered to linear logic and the approximation as a bottom-up logic program, work hand in hand. We could apply the general approximation methodology directly to ordered logical specifications, but in the case of ordered SSOS specifications, the loss of adjacency information that this would entail would result in approximations that are too coarse. We could (more realistically) ignore ordered logic and write our SSOS specifications directly in linear destination-passing style; this is, in fact, what was done for an earlier version of this paper [32]. However, and our experience with SSOS specification in ordered logic [26] has convinced us that the natural expression of adjacency in ordered logic really is an important element in the specification of programming languages.
In Section 2 we revisit the use of ordered logic as a specification framework and the transformation of ordered logical specifications into linear logical specifications. In Section 3 we discuss the approximation of ordered logic programs by saturating bottom-up logic programs. In Section 4 we apply these techniques to derive a control flow analysis and an alias analysis by logical approximation.

Ordered and linear logical specifications
The framework of ordered logical specifications that we present is a forward-chaining (or "bottom-up") logic programming language based on ordered logic. This framework is unlike most previous work in logic programming languages for substructural logics. 1 Traditionally, substructural logics have been treated as logic programming languages by giving a backward-chaining (or "top-down") operational semantics (in the style of Prolog) to the uniform fragment of the language -essentially the propositions freely generated by all connectives with invertible right rules [20]. Backward chaining operational semantics have been given to the uniform fragment of linear logic [13], ordered logic [28,29], and bunched logic [4].
Appropriate fragments of forward-chaining logic programming are less straightforward to isolate. The fragment of ordered logic we consider is split into a negative fragment of right-invertible connectives and a positive fragment of left-invertible connectives: Atomic Props. Q ::= p t 1 . . . tn Neg. Props. A ::= ∀x.A | S 1 S 2 Pos. Props.
S :: In the examples in the introduction we saw the use of ordered implication S 1 S 2 (where we call S 1 the premise and S 2 the conclusion), ordered conjunction S 1 • S 2 , and ordered atomic propositions Q. In addition, our language includes 1, the unit of ordered conjunction, existential quantification ∃x.S and universal quantification ∀x.S. Following a common convention we will treat uppercase variables as implicitly universally quantified: this is why rule 2 begins with "eval(app E 1 E 2 ) . . ." instead of "∀e 1 . ∀e 2 . eval(app e 1 e 2 ) . . .." We also have linear atomic propositions ¡Q, and persistent atomic propositions !Q. Persistent atomic propositions act like normal mathematical facts -when we assert a persistent atomic proposition in the conclusion of a rule, it stays true for the rest of the evolution of the system, so when we match against a persistent fact in the premise of a rule, the application of the rule does not remove that fact from the relevant set of facts. Linear atomic propositions, on the other hand, are ephemeral but not ordered: when they appear in the premise of a rule, the transition produced by the rule will remove the linear proposition from the multiset of linear atomic propositions. These connectives form the language of ordered logical specifications described in previous work [26]; we extend that language with a proposition (t = s) for equality between terms, which we will explains shortly.
We can define the meaning of propositions in ordered logic using a sequent calculus presentation of the logic. The judgment associated with ordered propositions is Γ ; ∆; Ω Σ A, which can be read as "under the persistent hypotheses Γ (which are subject to the usual rules of exchange, contraction, and weakening), the linear hypotheses ∆ (which do not admit contraction or weakening, only exchange), and the ordered hypotheses Ω (which admit none of these structural rules), A is true." We frequently elide the free parameters Σ.
To give an example, ordered conjunction is defined by the following rules: Here ∆ A ∆ B denotes a nondeterministic merge operation for linear contexts ∆ A and ∆ B . Read in a bottom-up way, the rule • R suggests that we can attempt to prove the conclusion A • B by separating out the linear context into two parts ∆ A and ∆ B and splitting the ordered context into a left part Ω L and a right part Ω R : in addition to the persistent assumptions in Γ , we must use ∆ A and Ω L to prove A and ∆ B and Ω R to prove B. Similarly, the rule • L , says that an ordered hypothesis A • B can be replaced in-place with an ordered hypothesis A followed by an ordered hypothesis B.
We will not reprise the full sequent calculus for ordered logic (see [29] or [26] or reconstruct it from the weakly focused rules in Figure 2), but we do extend the presentations there with rules for equality. These rules depend on a notion of complete sets of unifiers csu(Σ, t, s). A complete set of unifiers for two terms t and s with free parameters Σ is a set of substitutions for the free parameters Σ with two properties. First, every substitution θ in the set is a unifier of t and s, meaning θt and θs are syntactically identical up to renaming bound variables. Second, every unifier σ of t and s can be represented as the composition of some θ in the complete set of unifiers and another substitution τ . The = L rule can have zero or more premises depending on the size of the complete set of unifiers: Here we write Σ θ for a unifier θ with free variables in Σ . For general higher-order unification, calculating a complete set of unifiers csu(Σ, t, s) is undecidable. However, in the higher-order pattern fragment (which includes all first-order unification problems), it is not only decidable but unitary: either there are no unifiers of t and s or there is a unique most general unifier. On this fragment, then, we can proceed as if using derived rules = L and = Lmgu : This definition of equality based on unification follows [5] but is rather uncontroversial and dates back to Girard and Schroeder-Heister [12,30].

From ordered logic to ordered logical specifications
Now that we have briefly discussed the sequent calculus presentation for the relevant fragment of ordered logic, we can define the framework of ordered logical specifications by endowing that fragment with a forward-chaining operational semantics. We ultimately want to treat closed negative propositions as something like rewriting instructions. We call closed negative proposition rules and collections of rules programs (or specifications) if they obey the following four conditions: -Range restriction. Any variables appearing in the premise of a rule must have one strict occurrence [25], and every variable occurring in the conclusion of a rule must appear in a premise or as one of the existentially bound parameters in the conclusion. This ensures that higher-order matching is unitary and decidable so that we can always decide whether a particular rule may be applied [31]. -Pattern unification: In order to ensure that all occurrences of = L will have at most one premise, we require that every unification problem that appears in the conclusion of a rule fall in the pattern fragment [18]. 2 -Predicate separation: Each predicate must be used consistently, appearing either only in ordered, linear, or persistent atomic propositions in a given program. Therefore we can speak of predicates and propositions as being inherently ordered, linear, or persistent. -Rule separation: A rule with ordered conclusions must have ordered premises, and a rule with linear premises must have either linear or ordered premises.
Given these restrictions, the operational semantics of ordered logical algorithms are given by way of a focused sequent calculus in Figure 2. Focusing, introduced by Andreoli [3], is a restriction of the sequent calculus that forces derivations to alternate between two different phases -focused phases where non-invertible rules are applied Initial Rules In the focused presentation, Ω contains only positive propositions and ordered atomic propositions, ∆ contains only linear atomic propositions, and Γ contains only rules and persistent atomic propositions. The operational semantics of ordered logical specifications is described in terms of these focused sequents. A state is an unfocused sequent S = (Γ P Γ ; ∆; Ω ⇒Σ S) where the contexts Γ , ∆, and Ω contain only (persistent, linear, and ordered, respectively) atomic propositions, Γ P is a program, and the conclusion S is a closed positive proposition.

State transitions
We write "(Γ P Γ ; ∆; Ω ⇒Σ S) if Ω = Ω L Ω R and there is a sequential derivation of the following form (where A ∈ Γ P ): By a sequential derivation we mean that the derivation obeys two conditions: -The assumed sequent (Γ P Γ ; ∆ ; Ω ⇒ Σ S) is used exactly once in the partial derivation. This amounts to requiring that the conclusion S is not proved using right focus and that every occurrence of = L uses a most general unifier and therefore has exactly one premise. -The derivation does not include the rule focus L . This requirement forces the sequential derivation to consist of a partial derivation D inv using only left invertible rules (• L , 1 L , ! L , ¡ L , ∃ L , and = L ) above a partial derivation D foc using only the rules acting on left or right focused sequents (init, init¡, init!, L , • R , 1 R , ∀ L , ∃ R , and = R ).
The parameters Σ in the assumed sequent can be different from the parameters Σ in the conclusion due to new parameters introduced by applications of the ∃ L rule or due to the set of parameters being modified by the application of a most general unifier in the = L rule. We write "(Γ P Γ ; ∆; Ω ⇒Σ S) −+ −→ ⊥" (and say that the state Γ P Γ ; ∆; Ω ⇒Σ S aborts) if Ω = Ω L Ω R and if there is a complete derivation of the following form (where A ∈ Γ P ): where the complete derivation D inv uses only invertible rules (• L , 1 L , ! L , ¡ L , ∃ L , and = L ), and where the sequential derivation D foc uses only the rules acting on left or right focused sequents (init, init¡, init!, L , • R , 1 R , ∀ L , ∃ R , and = R ). Note that = L is the only left invertible rule that can have less than one premise, and only then if there is a contradictory unification goal. This can only arise if a contradictory unification goal is introduced in the conclusion of a rule.
Finally, we write "(Γ P Γ ; ∆; Ω ⇒Σ S) →|" if there is a complete derivation of the following form: This derivation necessarily stays entirely within right-focused sequents. In fact, it is decidable if (Γ P Γ ; ∆; Ω ⇒Σ S) →| holds because the required higher-order matching is decidable.
The connection between ordered logic and the language of ordered logical specifications is established by Theorem 1.

Theorem 1 (Nondeterministic completeness)
If the contexts Γ 0 , ∆ 0 , and Ω 0 contain only (persistent, linear, and ordered, respectively) atomic propositions, and if the context Γ P contains only rules obeying predicate separation and the restriction of equality to pattern unification, then there is a derivation of (Γ P Γ 0 ; ∆ 0 ; Ω 0 Σ0 S) in ordered logic if and only if there exists a sequence of transitions Proof Immediate consequence of Theorems 2 and 4 in [26] appropriately extended with the additional sequent calculus rules for equality.
Note that the nondeterminstic completeness of ordered logic programs only requires two of the four properties of programs: predicate separation and the restriction of equality to pattern unification. Range restriction is necessary in order to ensure that, given a state S, we can effectively enumerate all states S such that S −+ −→ S and determine whether Sn −+ −→ ⊥.

Notational Conventions
Throughout the paper, we will frequently be interested in the linear fragment -programs where the ordered context Ω starts off empty, and in the persistent fragmentprograms where both the ordered context Ω and the linear context ∆ start off empty. The restriction of rule separation ensures that states that start in the linear or persistent fragment will only evolve to states in the linear or persistent fragment, respectively. Because is a bit more familiar and less cluttered than writing we obey a convention that if we are unambiguously talking about the persistent fragment we will use ∧ instead of •, ⊃ instead of , and Q instead of !Q. Similarly, when we are unambiguously talking about the linear fragment, we will use ⊗ instead of •, instead of , and Q instead of ¡Q. We claim that a similarly-defined forward-chaining logic programming semantics for a framework of linear or persistent logical specifications would correspond exactly to the semantics that we get by expanding the definitions into the framework of ordered logical specifications. However, to avoid reprising the development in the previous section (twice!) we will not address that claim here.

Equivalence of Rules
Theorem 1 means that any derivation in our fragment of ordered logic can be characterized by a series of transitions driven by the rules A ∈ Γ P . This means that the impact of a rule A can be entirely characterized by the transitions S −+ −→ S and S −+ −→ ⊥ that it gives rise to. This in turn gives rise to a natural notion of equivalence between rules: two rules are equivalent when they give rise to the same transitions. The same idea appears in other focused proof systems as Andreoli's bipoles [2] and Chaudhuri's derived rules [10].
This becomes particularly relevant when we deal with the introduction of parameters by existential quantification which are are then "bound" using equality. For example, the following two rules are equivalent: Both rules lead from a state where at(t) (for arbitrary t) is in the persistent context to a state where next(t, s(t)) and at(s(t)) are also in the persistent context. We can see this is the case for the second rule by looking at the sequential derivation that the rule gives rise to.

Transformation into the linear fragment
As we mentioned in the Section 2.1.2, for the purposes of this paper we define linear logical specifications in terms of ordered logical specifications -we furthermore claim that this straightforwardly and unsurprisingly corresponds to a direct definition of linear logic programming. A somewhat more surprising result is that we can faithfully transform ordered logical specifications into linear logical specifications. 3 As discussed in the introduction, this transformation makes adjacency information (which amounts to control flow information) explicit in an SSOS specification. This in turn allows program analyses derived by approximation to utilize information about control flow that would be unavailable if we approximated an ordered SSOS specification directly. Therefore, the correctness of the transformation ensures that we can use the less cluttered style of substructural operational semantics in ordered logic without sacrificing control flow information in the analyses we derive by logical approximation. We write the translation of a state S i into the linear fragment as S i S . Transformed programs may generate spurious extra parameters, so we write S i + S to describe the transformation of a state S i that also includes free parameters that do not appear in S i or S i S . A correct transformation must be one where a transformed state exhibits precisely the same transitions as an untranslated state, as expressed by Theorem 2.

Theorem 2 (Correctness of transformation) For any three states
we have that In the remainder of this section we will present the translation (Section 2.2.1) and then discuss the proof of Theorem 2 (Section 2.2.2).

Definitions
where it is permissible for d L to be the same as d R -in other words, the transformation has three inputs. We translate ordered contexts Ω = S 1 . . . Sn by introducing n + 1 distinct parameters: Ω d0 dn = S 1 d0 d1 . . . Sn dn−1 dn ; therefore when we write Ω d0 dn , d 0 is the same as dn exactly when (Ω = ·).
Most of the complications in our setting are due to the fact that we have persistent and linear atomic propositions. This addition would break the correctness of the transformation into the linear fragment were it not for rule separation. If we do not force rule separation and have a rule like 1 Q which translates as , and the translated program can transition from a state where ∆ = . This is not equal to Q 1 QQ 2 d0 d2 because there are not 4 distinct parameters for the 3 propositions.
Rule separation prevents these problems, but leaves us with a choice: how should we translate a rule like (¡Q 1 ¡Q 2 )? We claim that the translated rule ¡Q 1 has the correct behavior, but the proof is complicated and inelegant: as a derivation is built bottom-up, the above rule would cause us to temporarily break the invariant that the n ordered propositions can be uniquely "threaded together" with n + 1 distinct parameters, but by the time we fully apply left invertible rules to reach a state, the invariant will always be restored. The simpler option is to say that the transformation of a program Γ P leaves every rule in the persistent or linear fragment alone, and only replaces A with A if A includes some ordered atomic propositions. This has the added nice property that the interpretation of programs is idempotent: Γ P = Γ P . Now that we have described the transformation of an ordered logical specification into the linear fragment, we can discuss the proof of its correctness.

Correctness
In this section, we present the proof of Theorem 2 with respect to successful transitions The proof with respect to halting transitions S 1 −+ −→ ⊥ is similar, and the proof with respect to terminating states S 1 →| is a direct consequence of Lemma 4.
Proof (Correctness of translation for transitions, Theorem 2a) Any transition begins by picking out a rule A ∈ Γ P . Using Lemma 1 to avoid dealing with the the program Γ P everywhere, it suffices to show: where both D and E are sequential derivations.
If A is in the persistent or linear fragment, then we know that A contains no mention of any of the predicates in Ω d0 dn , and so by invariants of this fragment (Lemma 3), it suffices to show: , implying left focus, or Ω 1 , implying left inversion. This proof (in both directions) is a straightforward induction on the structure of the derivation starting at the bottom and working up. Now we must consider the case where the premise of A contains ordered atomic propositions (the conclusion of the rule may or may not contain ordered atomic propositions). The reverse direction (completeness) is unsurprising: In the case that A = ∀x.A we use the induction hypothesis on the subderivation where the focus is on A [t/x]. In the case that A = S 1 S 2 , we have a derivation of this form: By E 1 and the correctness of right focus (Lemma 4) we know there is a derivation . By E 2 and the completeness of left inversion (Lemma 6) there is a sequential derivation D 2 : We can weaken and rename the parameters in D 1 and D 2 (Lemma 2) to construct the following: . . dn and Σw consists of the parameters used in the translation of Ω 1 but not in the translation of Ω L or Ω R . Because ∀d L .∀d R . S 1 S 2 , this completes the backward direction of the proof. The forward direction (soundness) is the direction that would fail were it not for rule separation: In the case that A = ∀x.A we again use the induction hypothesis on the subderivation where the focus is on A [t/x]. In the case that we have a derivation of this form: with the caveat that t L and t R are not known to be distinct and dn , the correctness of right focus (Lemma 4) and D 1 means that Because all the linear propositions that don't end up in ∆ 1 must be in ∆ 2 , we have If we let Ω L = Ω L and Ω R = Ω 1 Ω R , then we have Ω = Ω L Ω R as required.
By the soundness of left inversion (Lemma 7), D 2 , and strengthening of parameters (Lemma 2), we have ∆ l = ∆o Ωo d0 dm , Σ l = Σ Σwd 0 . . . dm (where Σw again contains all the parameters used in the translation of Ω 1 but not in the translation of Ω L or Ω R ), and a derivation E 2 : Using L , E 1 , and E 2 we obtain a sequential derivation ending in Γ ; ∆; Ω L [S 1 S 2 ]Ω R ⇒Σ S, which completes the forward direction. Proof Straightforward induction on derivations.

Lemma 3 (Invariants of the linear fragment) If
A is a rule in the persistent or linear fragment which contains no mention of any of the predicates in the linear context ∆ t , and D is a sequential derivation from the state Γ P Γ ; ∆ ; Ω ⇒ S to Γ P Γ ; ∆∆ t ; Ω L [A]Ω R ⇒ S, then Ω = Ω L Ω R and ∆ = ∆ ∆ t .
Proof Induction over the structure of the sequential derivation; we have to generalize the induction hypothesis to allow the bottom of the derivation to either have a left focus [A] or an ordered context Ω containing no ordered atomic propositions. We also need a lemma stating a similar property for right-focused derivations, that if S contains no ordered propositions and contains no mention of any of the predicates in ∆ t , then Γ ; ∆; Ω ⇒ [S] implies (Ω = ·) and that ∆ is disjoint from ∆ t . This lemma is also proved by straightforward induction on the structure of the derivation. Proof Induction on the length of the derivation. The "smaller" part is critical, as it justifies feeding the resulting derivation into the induction hypothesis.
Proof Lexicographic induction: either the length of the derivation D gets smaller or stays the same while the size of the ordered context Ω 1 decreases. We proceed by case analysis on the structure of Ω 1 . We give three representative cases: If (Ω 1 = ·), then D cannot take any steps, and the result is immediate (with Γ = Γ , ∆ = ∆ , and Ω = Ω L Ω R . If (Ω 1 = (S 1 • S 2 )Ω), then by invertibility (Lemma 5) we have a smaller derivation ending in Γ ; ∆; Ω L S 1 S 2 ΩΩ R ⇒Σ S. We can get a transformed derivation ending in: This completes the case.
If (Ω 1 = QΩ), then we use the induction hypothesis on the same derivation where (Ω L = Ω L Q) and (Ω 1 = Ω) -this is the case where we use the lexicographic induction, as the ordered context gets smaller but the size of the derivation stays the same. We get a transformed derivation ending in: This completes the case.

Lemma 7 (Soundness of translation for left inversion)
For any contexts Γ , ∆ , Ω , Γ , ∆, Ω L , and Ω R containing only atomic propositions, Proof Induction on the length of the derivation D, repeatedly invoking invertibility (Lemma 5) as in the proof of Lemma 6.

Linear destination-passing style
To conclude this section, we will make an observation about the result of passing ordered SSOS specifications to through the transformation we have described. If we transform the ordered SSOS specification of the call-by-value lambda calculus from the introduction (rules 1-4) into a linear logical specification, we get the following: Note that the third argument of eval/retn is essentially meaningless -it is always passed on intact from the premise the conclusion. This simply reflects the fact that our control stack grows out to the left, and we are never concerned with what is to the right of an eval or retn atomic proposition. Additionally, a rule that binds an existential parameter in its premise is equivalent to one that binds the same parameter universally. By removing the vestigial D and universally quantifying where appropriate, we can rewrite this program into an essentially equivalent one: This program is significant because it is an example of a linear SSOS specification using linear destination-passing style -the parameters introduced by the translation are called destinations because we think of D in eval E D as the eventual destination of the result of evaluating E. Linear destination-passing style was the original form of substructural operational semantics specifications before ordered logic was considered as a framework [23,9]. The fact that linear destination-passing style arises naturally from the transformation of an ordered SSOS specification into linear logic is a new observation, and is interesting in its own right. 4 For the purposes of our current discussion, the transformation to destination-passing style is important primarily because the destinations make control flow information explicit. As we will see, this explicit representation of control flow is what will make it possible to derive program approximations that are sensitive to control flow.

Saturating forward-chaining logic programming
We have presented the language of ordered logical specifications, which we think of as a state transition system. We usually think of implementing these specification languages by a forward-chaining logic programming language with a committed choice semantics. This means that if the state can evolve in two different but possibly mutually exclusive ways, we arbitrarily pick one transition and do not reconsider that choice, and once a state is reached from which no transitions are possible, evaluation halts (we say it has reached quiescence) [16,32,26]. This makes sense for ordered and linear logical specifications, but when we consider persistent specifications the story is different. The use of a persistent proposition in a premise does not remove that persistent proposition from the context. This means that if we make a given transition once, we can make it again (deriving a new copy of all the facts in the conclusion), and it also means that those new facts will not matter, because one copy of a fact is as good as two.
A state S in which any rule application only re-derives known facts is said to be saturated. A saturating semantics for logic programs allows only transitions that derive previously unknown facts. Saturating logic programs need not always terminate, but if a program reaches a saturated state it will terminate. A program with existential parameters in the conclusion will usually only terminate if the parameters are unified with ground terms through the use of equality -otherwise we could productively apply the rule to create a new parameter along with a new fact containing that parameter. Effective ways of implementing saturating logic programs are dealt with elsewhere (see, for example, [17]), and we will not discuss them here. 5 In this section, we describe an approximation methodology in which we can approximate logical specifications as persistent logical specifications. If those persistent logical specifications can also be run as terminating saturating logic programs, we obtain a way of approximating the behavior of logically specified systems.

Approximating ordered logic programs as saturating logic programs
Our approximation strategy is extremely simple: essentially, an approximation of an ordered or linear logical specification is generated by making all atomic propositions persistent, removing premises, and adding conclusions. Of particular practical importance are added conclusions that equate parameters introduced by existential quantification and ground terms: all such parameters must be equated with ground terms in order to interpret a persistent specification as a saturating logic program.
First, we give a precise definition of what it means for a program to be an approximate version of another program.

Definition 1 A program
Γa is an approximate version of another program Γ P if Γa is in the persistent fragment, and if, for each rule in Γa: the existential parameters are identical to the existential parameters of the corresponding rule in Γ P the premises are a subset of the premises of the corresponding rule in Γ P , and the conclusions are a superset of the conclusions of the corresponding rule in Γ P .
Next we give a definition of what it means for a state to be an approximate version (we use the word "generalization") of another state or of a family of states. For the purposes of defining generalizations of a state (Γ P Γ ; ∆; Ω ⇒Σ S) we are uninterested in the program Γ P or the conclusion S. We use a different notation describing states as tuples Σ, Γ, ∆, Ω to emphasize this. A series of states S 1 Definition 2 A state Σg, Γg, ·, · is a generalization of a state Σ, Γ, ∆, Ω if there is a substitution function Σg θ : Σ such that, for all propositions A ∈ Γ, ∆, Ω, there exists a proposition Ag ∈ Γg such that θA = Ag. The meta-approximation theorem relates the definition of abstraction above to the concept of an approximate version of a program as specified by Definition 1.

Theorem 3 (Meta-approximation) If
Γa is an approximate version of Γ P , S 0 = Σ 0 , Γ 0 , ∆ 0 , Ω 0 is an initial state of Γ P , and if Σ 0 , θ(Γ 0 ∆ 0 Ω 0 ), ·, · −+ −→ . . . −→ S n of the approximate program such that S n generalizes Sn -according to Lemma 9 this trace could also abort, but we assume in the statement of the theorem that this will not happen. Then, by Lemma 11 (Saturation), we know that the saturated state Sa is a generalization of S n . Because generalization is transitive, Sa is a generalization of Sn, which is what we needed to show.
The meta-approximation theorem relies on four lemmas that are described below. The first two lemmas establish that an approximate version of a program can simulate the program it approximates, and next two formalize the notion that, in an approximate version of a program, the saturated database at the conclusion of a complete program trace captures all of the "behaviors" of that approximate program. These two facts in combination mean that all of the behaviors of a program are captured by the saturated database at the conclusion of a complete trace of its approximate version. Proof We consider the sequential derivation representing the transition in the focused sequent calculus. We will show that if there is a sequential derivation from Γ ; ∆ ; Ω ⇒ Σ S to Γ ; ∆; Ω L [σA]Ω R ⇒Σ S and Σg, Γg, ·, · is a generalization of Σ, Γ, ∆, Ω L Ω R (associated with the substitution Σg θ : Σ), then there is a sequential derivation from Γ g ; ·; · ⇒ Σ g S to Γg; ·; [θ(σAa)] ⇒Σ g S such that Σ g , Γ g , ·, · is a generalization of Σ , Γ , ∆ , Ω . The substitution σ just tracks what terms have been substituted for the universally quantified variables in A.
As usual, the case where the last rule is ∀ L is a fairly straightforward application of the induction hypothesis, and the critical case is when the last rule is L . In that case, we have the following: The approximate version of S 1 S 2 is S 1 S 2 , and we have E 1 :: Γg; ·; · ⇒Σ g θ(σS 1 ) by induction over the structure of S 1 . Because all the components of S 1 also appear in S 1 , when we need to establish that Γg; ·; · ⇒Σ g [!(θ(σQ))], we know that D 1 must contain a derivation of !(σQ), ¡(σQ), or (σQ). This means that (σQ) is somewhere in the original state, and therefore θ(σQ) ∈ Γg, which completes the case. The cases where S 1 is not an atomic proposition are similar.
The most interesting case is where Ω 2 is (t = s)Ω . It may be the case that θ(σt) and θ(σs) are not unifiable, in which case the generalization aborts (as the lemma allows). Assume, on the other hand, that θ(σt) and θ(σs) have a most general unifier τ , where (Σ g τ : Σg). If the equality t = s appears only in the approximate version, then because Σg, Γg, ·, · is a generalization of Σ, Γ, ∆, Ω , Σ g , τ Γg, ·, · is also generalization of Σ, Γ, ∆, Ω , so we can apply the induction hypothesis (D 2 is the same size and Ω 2 is smaller) to get E 2 ending in (τ Γg; ·; τ (θ(σΩ )) ⇒ Σ g τ S), and we conclude by applying = L . If, on the other hand, the equality t = s appears in both the original and approximate versions, then we have a second most general unifier (Σ τ : Σ) of σt and σs by inversion on D 2 . To apply the induction hypothesis we must show that Σ g , τ Γg, ·, · is a generalization of Σ , τ Γ , τ ∆, τ Ω , which amounts to showing that if A ∈ (Γ ∪ ∆ ∪ Ω), then θ(τ A) ∈ τ Γg. We have that θA ∈ Γg by the generalization we do know about, so certainly τ (θA) ∈ τ Γg. Because τ is the mgu of two terms and τ is the mgu of θ applied to those terms, θτ = τ θ so θ(τ A) = τ (θA) and the generalization holds. Therefore, we can apply the induction hypothesis (D 2 is smaller) and conclude as before.
−→ Sn is a trace of a program Γ P , if Σ 0 θ : Σ, and if Γa is an approximate version of Γ P , then there exists a trace of the program Γa starting from Σ 0 , θ(Γ ∆Ω), ·, · that either aborts or reaches a state S n that is a generalization of Sn.
Proof By induction on the length of the program trace. The base case is immediate and the inductive case follows from Lemma 8. Proof By induction on the general trace S 0 , . . . , Sn. The base case follows from Lemma 10 -Sa generalizes S 0 because the latter evolved from the former.
In the inductive case, Sa is a generalization of Sn, and Sn that evolves to S n+1 . We need to show Sa is a generalization of S n+1 . By Lemma 8, Sa evolves to S + a , which is a generalization of S n+1 . Because generalization is transitive, it suffices to show that Sa is a generalization of S + a . But Sa is saturated, so every parameter or proposition in S + a is equal to a parameter or proposition in Sa.
Lemmas 9 and 11 give us the pieces needed to complete the proof of the metaapproximation theorem.

Termination and Skolemization
A consequence of the meta-approximation theorem is that we are interested in the termination of saturating logic programs, because a terminating approximate version of a program gives us a way to generate a single state Sa that captures all possible behaviors of the original program. Important classes of programs are known to terminate in all cases, such as those in the so-called "Datalog fragment" where the only terms in the program are variables and constants. The approximations we consider do not fall into these fragments, but general reasoning about the termination of saturating logic programs is not difficult. Because each transition in a saturating logic program must derive at least one new fact, any logic program that can derive only finitely many facts from any (finite) initial state will necessarily terminate.
A common design pattern in saturating logic programs is to enumerate the subterms of a term and then perform a computation on those subterms; because a term has finitely many subterms, we can be sure such programs terminate. If we wanted to enumerate the subterms of arithmetical expressions that take the form we could use the following rules: But what if we want to add to the language of expressions functions and function application?
The rule for app is obvious, but the immediate subterm of lam(λx.E x) is (λx.E x), which is a higher-order term -in order to get a subterm that is a term of base type, we must substitute something for the bound variable x. One approach would be to generate a new existential parameter y to substitute for x (as usual, we perform substitution by application).
subterms(lam(λx.E x)) ⊃ ∃y. subterms(E y) This is a non-terminating logic program: if the rule for lam can be applied at all it can be applied repeatedly, generating a new name each time. However, the quantifier dependence between E (which is implicitly universally quantified) and y in this rule suggests Skolemization: instead of generating a new name every time a rule is applied, we replace y by a Skolem function var which depends on E.
subterms(lam(λx.E x)) ⊃ subterms(E(var(λx.E x))) In this representation, a variable is effectively a pointer back to its binding site; as long as we never follow those pointers by matching against var in the premise of a rule, then we can bound the number of subterms we will consider. This ensures that we will only consider a finite number of facts of the form subterms(E), which in turn ensures termination.

Example
To conclude this section, we give a simple example of how Skolemization can be integrated with our approximation strategy. Consider a linear logical specification where a linear proposition at(x) represents a piece of stateful information (that we are at position x) and a persistent proposition !next(x, y) represents a piece of persistent information (we were at position x immediately before being at position y). We can represent this system with the following rule: at(X) ∃y. !next(X, y) ⊗ at(y) We will consider the process of successively approximating this rule to get a terminating saturating logic program. The most obvious approximate version of rule 16 simply turns all propositions persistent: at(X) ⊃ ∃y. next(X, y) ∧ at(y) While rule 17 is a persistent logical specification, it is not a saturating logic program because it of the existentially quantified variable y in the conclusion. As discussed in the previous section, we can perform Skolemization by introducing a Skolem function s which depends on x.
at(X) ⊃ next(X, s(X)) ∧ at(s(X)) One problem here is that rule 18 doesn't quite fit our criteria for being an approximate version of rule 16. An equivalent rule, one where the existential parameter is left in place but then equated with s(X), is an approximate version of rule 16.
at(X) ⊃ ∃y. next(X, y) ∧ at(y) ∧ (y = s(X)) A different problem still remains. This approximate version of rule 16 is not saturatingfor any state, we can always generate a larger one. To deal with this problem, we observe that the Skolem function need not depend on all universally quantified variables. In this particular case, instead of the Skolem function s(n) (for "successor"), we can think about the Skolem function p (for "positive") and define the following rule: at(X) ⊃ ∃y. y = p ∧ next(X, y) ∧ at(y) Rule 20 is both an approximate version of rule 16 according to our criteria as well as a saturating logic program that will terminate: starting from the state where at(0) is true, we will learn at(p), next(0, p), and next(p, p) -if we think of p as a stand-in for the positive-numbers, this represents that the successor of 0 is a positive number and that the successor of a positive number is a positive number. Because we can effectively Skolemize existential variables with the addition of conclusions relating to equality, the use of restricted Skolem functions with equality is our standard means of managing existential quantification and finding an approximation which is manageable as a terminating logic program. Therefore, when we use Skolemization with higher-order functions as described above, it will look less like rule 15 and more like rule 21: In the rest of the paper, our default position when encountering a parameter substituted into a higher-order function (λx.E x) will be to equate that parameter with var(λx.E x), even if the rule has other universally quantified variables.

Approximating SSOS specifications for program analysis
So far, we have discussed four pieces: ordered logical specifications and substructural operational semantics (Section 2), the transformation of ordered logical specifications to linear logical specifications (Section 2.2), the approximation of logical specifications by persistent logical specifications (Section 3.1), and the use of Skolemization in particular to ensure that persistent logical specifications can be interpreted as saturating logic programs which always terminate (Section 3.2). In Section 2.3 we connected the former two pieces by showing how applying the transformation to ordered SSOS specifications gave rise to linear SSOS specifications exhibiting destination-passing style, and in Section 3.3 we showed how the latter two pieces fit together by deriving a terminating approximation from a linear logical specification. In this section, we will present two examples that connect all four pieces. First, in Section 4.1, we will take a variant of the call-by-value operational semantics that we considered in the introduction and Section 2.3 and derive a context-insensitive control flow analysis. Second, in Section 4.2, we will take an SSOS specification of a monadic functional language with Lisp-like mutable cons cells and derive an interprocedural alias analysis. Figure 4 contains three steps in our approximation of a call-by-value program semantics to a context-insensitive control flow analysis. The starting point, the ordered SSOS specification, differs from the previous presentation (rules [1][2][3][4] in two ways. The first difference, the addition of a new stack frame call which is introduced when a function is applied in rule 26 and eliminated in rule 27. It will allow a more precise approximation by identifying call sites. The second difference is more interesting: the use of what was previously called an "environment semantics" for SSOS specifications [26]. In rule 26, instead of substituting the argument of a function for the function's bound variable as we did in rule 4, we generate a new parameter y, substitute that for the bound variable, and then generate a persistent fact !bind y V 2 that permanently associates the Call-by-value SSOS specification with destinations for binding

Control flow analysis
Translation to the linear fragment Approximation to context-insensitive control flow analysis parameter with the argument V 2 . A second rule (rule 22) ensures that when we come across one of these parameters in the course of evaluation, we can "look up" the associated value by finding the (unique) fact associated with it in the form of a persistent proposition !bind X V . This modification makes binding information amenable to approximation in roughly the same way destinations make control information amenable to approximation. The first step in deriving a control flow analysis is the transformation of the ordered SSOS specification into a linear SSOS specification. We give the result of our translation in rules 28-33. 6 As we observed before, the vestigial D destination is not needed, and whenever we mention a persistent bind proposition we must put an equality in the rule even though the rule is obviously equivalent to a rule that does not have that equality in it.
In rules 34-39, we take a suitably equivalent version of the linear specification (one that does not have the vestigial third argument for eval and retn, nor the unnecessary uses of equality) and derive a persistent approximation that can be run as a saturating logic program. In rule 38, as our methodology suggests, we equate the parameter y with the Skolemization of the function it is being substituted into, var(λx.E 0 x). Therefore, assuming we start a saturating logic program with the single atomic proposition eval E D, we only deal with subterms of E as defined by Section 3.2, and we can be certain that we have a saturating logic program that will terminate on any input. Furthermore, all rules maintain the invariant that when evaluating eval E D, the parameter D is always equated with E -we could simplify the program further by only having a single argument to eval. The retn relation in the saturated program, then, is critical: retn V D, where D = E for some subexpression E, says that during the course of evaluation E may evaluate to the value V .
One question that flow analysis is intended to answer is, "for any given call site in the source program, what are the functions that might be invoked at that location?" Each fact of the form comp call E E 0 represents that the evaluation of E (the application expression that we are trying to evaluate to a value) may result in an attempt to evaluate E 0 (the body of the function that has been called). This means that the call site represented by the expression E will invoke only functions E 0 such that comp call E E 0 is in the saturated state. Conversely, the absence of such a fact means that the function with body E 0 can never be invoked from the call site E.
There is one important caveat to this analysis. If we take the program app (lam(λx.x)) (app (lam(λy.y)) V ) we might expect a reasonable control flow analysis to notice that only lam(λy.y) is passed to the function lam(λx.x) and that only V is passed to the function lam(λy.y).
Because of our use of higher-order abstract syntax, lam(λx.x) and lam(λy.y) are syntactically identical (names of bound variables don't matter). This is obviously not a problem with correctness, but it means that our analysis may be less precise than expected. One solution would be to add distinct labels to term. Adding a label on the inside of every lambda-abstraction would seem to suffice, and in any real example labels would already be present in the form of source-code positions or line numbers. The next example, alias analysis, discusses the use of these labels.

Alias analysis
We will use our approximation methodology to derive an interprocedural alias analysis in the context of a simple language of straight-line functions and Lisp-like mutable pairs; the resulting approximation bears a strong resemblance to the object-oriented alias analysis presented as a logic program in [1,Chapter 12.4]. The language has the following syntax: Expressions E should be thought of as sequences of let-bindings let x = M in E that bind the result of a command M in the remainder of a program or else choose a variable as the returned value of the function. Commands are either procedure definitions (fun (λx.E 0 x)), procedure calls (call F X calls the procedure F with the argument X), create pairs (newpair), projections from the first or second component of a pair (proj X C), or assignments to the first or second component of a pair (set X C Y ). Finally, each return statement or command is given a label L, which we can think of as a line number from the original program.
The rules for functions are unsurprising; as in the previous section, we use destinations for binding. We have comp and eval predicates. as before, though we can do without retn. 7 The rules for mutable pairs use linear atomic propositions for the first time in an ordered logical specification. Each destination D created by a newpair command is associated with two linear atomic propositions: ¡cell D fst V 1 contains the first projection V 1 , and ¡cell D snd V 2 contains the second projection V 2 , both of which are initially set to null.
∃y. eval(E y) • !bind y null • ¡cell D C V When we approximate the specification in rules 40-45, our methodology forces our hand almost completely: once we equate every existential y with the Skolemization of the function it is being substituted into, there are only two existentially generated parameters left to consider: the destination generated when we create a new pair in (rule 43), and the destination created by the translation to linear destination-passing style in the rule handling procedure calls (rule 41). One option is just equate the destinations with the Skolemized function we are using in the same rule: this is shown in Figure 5, and the termination arguments are much the same as they were in the control-flow analysis.
Because the labels uniquely identify subterms of the original program, this alias analysis is not subject to the same caveat as the control flow analysis we considered before. Furthermore, these labels also allow us to consider an alternative to Skolemization. With one exception, the function call in rule 47, every Skolem function we generate is of the form var(λx.E x) that originates from an expression (let L M (λx.E x)). In other ⊃ ∃y. eval (E y) D ∧ bind y null ∧ cell D X C V ∧ (y = var(λx.E x)) words, each of these Skolem functions, can be uniquely associated with a label L, so we can think about using this label instead of var(λx.E x). In Figure 6 we show a modified version of the rules for mutable state where labels are used instead of Skolem functions. One benefit of the use of labels is that it makes the answer to some of the primary questions asked of an alias analysis much clearer. For instance, we want alias analysis to tell us whether the first or second component of a pair created at label L 1 can ever reference a pair created at label L 2 . In the modified version of the rules, the first component of a pair created at label L 1 might reference a pair created at label L 2 if cell L 1 fst (loc L 2 ) appears in the saturated database, and likewise for the second component.

Conclusion
We have defined a framework of ordered, linear, and persistent atomic propositions with higher-order terms and equality assertions. This framework is suitable for writing interpreters for programming languages in the style of substructural operational semantics. These specifications in ordered logic can be automatically transformed to linear logical specifications and then approximated as persistent logical specifications. By running these persistent logical specifications as saturating logic programs, we generate static analyses of programs written in those languages. The relative ease of encoding two rather different analyses, alias analysis and control flow analysis, suggests that our technique can be used to derive other program analyses.
Our methodology presented Skolemization and the addition of equality constraints as essentially the only tool for restricting persistent logic programs in order to ensure termination. Another possibility considered in the conference version of this paper was to use explicit congruence rules such as allowing the term s(s(0)) to be equal to 0 in a non-contradictory way (and thereby only considering natural numbers modulo 2) and allowing lists that agree on their first k elements to be treated as equal. This is a powerful addition, but its interaction with the sequent calculus rules we gave for equality, which rely on the definition of higher-order unification, is not straightforward. There are two ways of thinking about equality in proof search and logic programming. The one we have adopted in this work is based on unification and is usually attributed to Girard and Schroeder-Heister [12,30]. Another view that is closer to the one from the conference version of this paper is based on constraints, has been explored in different settings by Virga and Saraswat et al. [34,14].
A richer set of approximation tools based on constraints or a more congruenceclosure-like conception of equality could be developed entirely within the realm of saturating logic programs and still integrated into the development we have presented here. We have considered a two step methodology in this work: an automatic transformation of an ordered specification into a linear specification followed by a manual approximation of the linear specification to obtain a terminating bottom-up logic program. We could adapt our methodology to a three step process: an automatic transformation of an ordered specifications into a linear specifications, an automatic derivation of a kind of "collecting semantics" by simply turning linear predicates persistent, and finally a manual approximation of the resulting non-terminating saturating logic program by a terminating logic program. This means that the work we have presented here can potentially be extended with more powerful approximation techniques without dealing with the added complexity introduced by substructural logics.

Related work
This work is similar to work by Bozzano et al. [7,8] in both its goals and its methodology. They encode distributed systems and communication protocols in a framework that is roughly equivalent to the linear fragment of our specification framework without equality. Abstractions of those programs are then used to verify properties of concurrent protocols that were encoded in the logic [6]. However, the style they use to encode protocols is significantly different from our SSOS style of specification, and a general purpose approximation is used, in contrast to our methodology of describing a whole class of approximations. Furthermore, Bozzano et al.'s methods are designed to consider properties of systems as a whole, not static analyses of individual inputs as is the case in our work.
A fundamentally different kind of approximation of linear logic programs via predicate substitution has been described by [19]. Miller's approximations remain linear, which we have ruled out so far in order to obtain a simple meta-approximation theorem.
Another line of related work is the use of the ∇ quantifier [21] for name generation, which we could have used here instead of the existential quantifier, although the difference does not become significant until we carry out formal meta-reasoning [33]. As a point of future work we conjecture it may be possible to apply our use of Skolemization in the realm of reasoning with and about generic judgments.
This article focuses on the process of deriving saturating logic programs from operational semantics specifications, but the work suggests many directions of research for saturating (i.e., bottom-up) logic programs in the persistent fragment. It is not obvious how the metacomplexity theorems for bottom-up logic programs originally presented by McAllester [17] should be generalized to a setting with equality and higher-order terms.