Lazy Narrowing with Simplification^{∗}

Michael Hanus

Informatik II, RWTH Aachen D-52056 Aachen, Germany

                        hanus@informatik.rwth-aachen.de

Preliminary version. Final version in Journal of Computer Languages (Elsevier), Vol. 23, No. 2–4, pp. 61–85, 1997

Abstract

Languages that integrate functional and logic programming styles with a complete operational semantics are based on narrowing. In order to avoid useless computations, lazy narrowing strategies have been proposed in the past. This paper presents an improvement of lazy narrowing by incorporating deterministic simplification steps into lazy narrowing derivations. These simplification steps reduce the search space so that in some cases infinite search spaces are reduced to finite ones. We consider two classes of programs where this strategy can be applied. Firstly, we show soundness and completeness of our strategy for functional logic programs based on ground confluent and terminating rewrite systems. Then, we show similar results for constructor-based weakly orthogonal (not necessarily terminating) rewrite systems. Finally, we demonstrate the improved operational behavior by means of several examples. Since most functional logic languages are based on programs belonging to one of these classes, our result is a significant step to improve the operational semantics of existing functional logic languages.

1 Introduction

In recent years, a lot of proposals have been made to amalgamate functional and logic programming languages [22]. Functional logic languages with a sound and complete operational semantics are based on narrowing, a combination of the reduction principle of functional languages and the resolution principle of logic languages. Narrowing, originally introduced in automated theorem proving [43], is used to solve equations by finding appropriate values for variables occurring in arguments of functions. This is done by unifying (rather than matching) an input term with the left-hand side of some rule and then replacing the instantiated input term by the instantiated right-hand side of the rule.

Example 1.1 Consider the following rules defining the addition of two natural numbers which are represented by terms built from 0 and s:

\begin{matrix}0 + y → & y & (R_{1}) \\ s(x) + y → & s(x + y) & (R_{2}) \end{matrix}

∗This paper is a revised version of papers appeared in the proceedings of ESOP’94 and PLILP’94.

The equation z + s(0) ≈ s(s(0)) can be solved by a narrowing step with rule R_{2} followed by a narrowing step with rule R_{1} so that z is instantiated to s(0) and the instantiated equation is reduced to the trivial equation s(s(0)) ≈ s(s(0)):

z + s(0) ≈ s(s(0)) ⇝_{{z↦s(x)}} s(x + s(0)) ≈ s(s(0)) ⇝_{{x↦0}} s(s(0)) ≈ s(s(0))

Hence we have found the solution z ↦ s(0) to the given equation. □

In order to ensure completeness in general, the left-hand side of each rule must be unified with each nonvariable subterm of the given equation. Clearly, this yields a huge search space. The situation can be improved by particular narrowing strategies which restrict the possible positions for the application of the next narrowing step, e.g., basic [26], innermost [14], outermost [11], lazy [41], or needed narrowing [2]. In this paper we consider lazy narrowing strategies where narrowing steps are applied at outermost positions in general and at an inner position only if it is demanded and contributes to some later narrowing step at an outer position. Similarly to pure functional programming, such a lazy strategy avoids useless steps in comparison to an eager strategy. However, in the context of functional logic programming, a lazy narrowing strategy can also have an unpleasant behavior if a demanded argument term has infinitely many head normal forms (i.e., if it can be derived to infinitely many terms with a variable or constructor at the top).

Example 1.2 Consider the following rules which may be part of a program for arithmetic operations:

\begin{matrix}0 ∗ x → & 0 & (R_{3}) & one(0) → & s(0) & (R_{5}) \\ x ∗ 0 → & 0 & (R_{4}) & one(s(x)) → & one(x) & (R_{6}) \end{matrix}

If we want to compute a solution to the equation one(z) ∗ 0 ≈ 0 by lazy narrowing, we could try to apply rule R_{3} to evaluate the left-hand side. In this case the first argument one(z) is demanded and must be evaluated to a term with a constructor at the top. Unfortunately, there are infinitely many possibilities to compute a head normal form s(0) of the term one(z) by instantiating z with \underbrace{s(⋯ s}_{n}(0) ⋯) for arbitrary n. Hence lazy narrowing has an infinite search space in this example and

does not compute a solution in a sequential implementation (see [18] for a discussion of problems with sequential implementations of lazy narrowing). However, we could avoid this infinite search space by computing the normal form of both sides of the equation before applying a narrowing step. The normal form of the initial equation is 0 ≈ 0 (reduction of the left-hand side with rule R_{4}) which is trivially true. □

The idea of reduction to normal form before applying a narrowing step has been mainly proposed with respect to eager narrowing strategies [13, 14, 25, 38, 42]. It has been shown that eager narrowing with normalization is a more efficient control strategy than left-to-right SLD-resolution for equivalent logic programs [14, 21]. On the other hand, only little work has been done to improve the efficiency of outermost or lazy strategies. Echahed [12] has shown the completeness of any narrowing strategy with simplification under strong requirements (uniformity of specifications). Dershowitz et al. [9] have proposed to combine lazy narrowing with simplification and demonstrated the usefulness of inductive consequences for simplification. However, they have not proved completeness of their lazy unification calculus if all terms are simplified to their normal form after each unification step.^{1}

The main contribution of this paper is the combination of lazy narrowing with intermediate simplification steps. We show that this combination does not destroy the completeness of lazy narrowing. We prove this result for the following two classes of functional logic programs.^{2}

1. Ground confluent and terminating rewrite systems: All existing proposals for combining narrowing with simplification require terminating rewrite systems [13, 14, 25, 38, 42]. For this case, narrowing is a method to compute unifiers in the presence of an equational theory (known as E-unification, see [3] for a survey). We will develop a calculus for this class, called lazy unification with simplification, and provide a rigorous completeness proof. This calculus has a lazy behavior w.r.t. unification, i.e., functions are only evaluated if their value is required to decide the unifiability of terms. Moreover, we allow to use program rules as well as additional inductive consequences for simplification between narrowing steps. This has been proved to be useful in other (eager) calculi [12, 14, 38].

2. Weakly orthogonal (not necessarily terminating) rewrite systems: If the functional logic program is not based on a terminating rewrite system, a lazy narrowing strategy is needed [6, 35, 41]. Since normal forms may not exist in the presence of nonterminating functions, equality between two expressions is interpreted as strict equality in such languages (e.g., BABEL [37], K-LEAF [17]), i.e., two expressions are equal iff they are reducible to a same ground constructor term. The confluence of the rewrite system is ensured by syntactic criteria (left-linearity and nonambiguity). Lazy narrowing is a complete method to compute unifiers w.r.t. strict equality for such programs. However, no attempt has been made to use program rules for simplification between narrowing steps. Due to the absence of normal forms for some expressions, full normalization between narrowing steps would be incomplete. Therefore, we propose the integration of lazy simplification into lazy narrowing derivations for such programs.

As far as we know, all functional logic languages with a complete operational semantics are based on programs belonging to one of these classes. For instance, programs with the requirements of ALF [19], LPG [4] or SLOG [14] are ground complete and terminating, whereas programs with the requirements of BABEL [37] or K-LEAF [17] are weakly orthogonal. Thus our result is a significant step to improve the operational semantics of existing functional logic languages. We will emphasize this point by discussing the advantage of lazy narrowing with simplification for various classes of functional logic programs.

In the next section we recall basic notions from term rewriting and functional logic programming. In Section 3 we present the lazy unification calculus with simplification and prove its soundness and completeness for ground confluent and terminating rewrite systems. In Section 4 we show how to include a deterministic simplification process into lazy narrowing derivations w.r.t. weakly orthogonal rewrite systems. In Section 5 we discuss the usefulness of this simplification process for different classes of functional logic programs. Finally, we conclude with a discussion of related work.

1In fact, their completeness proof for lazy narrowing does not hold if eager rewriting is included since rewriting in their sense does not reduce the complexity measure used in their completeness proof and may lead to infinite instead of successful derivations.

2For the sake of simplicity, we consider only programs based on unconditional rewrite systems. However, it does not seem difficult to extend the results of Section 4 to conditional rules with extra variables in conditions using the transformation techniques presented in [24].

2 Preliminaries

In this section we recall basic notions of term rewriting [8] and functional logic programming [22].

A signature is a set F of function symbols.^{3} Every f ∈ F is associated with an arity n, denoted f/n. Let X be a countably infinite set of variables. Then the set T (F, X) of terms built from F and X is the smallest set containing X such that f(t_{1}, …, t_{n}) ∈ T (F, X) whenever f ∈ F has arity n and t_{1}, …, t_{n} ∈ T (F, X). We write f instead of f() whenever f has arity 0. The set of variables occurring in a term t is denoted by Var(t) (similarly for the other syntactic constructions defined below, like equation, rewriting rule etc.). A term t is called ground if Var(t) = ∅. In the following we assume that F is a signature with at least one constant.

The execution of functional logic programs requires notions like substitution, unifier and subterm which will be defined next. A substitution σ is a mapping from X into T (F, X) such that its domain Dom(σ) = {x ∈ X | σ(x) ≠ x} is finite. We frequently identify a substitution σ with the set {x ↦ σ(x) | x ∈ Dom(σ)}. Substitutions are extended to morphisms on T (Σ, X) by σ(f(t_{1}, …, t_{n})) = f(σ(t_{1}), …, σ(t_{n})) for every term f(t_{1}, …, t_{n}). A substitution σ is called ground if σ(x) is a ground term for all x ∈ Dom(σ). The composition of two substitutions ϕ and σ is defined by ϕ ∘ σ(x) = ϕ(σ(x)) for all x ∈ X. The union of two substitutions ϕ and σ is defined by

(ϕ ∪ σ)(x) = \{ \begin{matrix}ϕ(x) & if x ∈ Dom(ϕ) \\ σ(x) & if x ∈ Dom(σ) \\ x & otherwise \end{matrix}

only if Dom(ϕ) ∩ Dom(σ) = ∅. The restriction σ_{|V} of a substitution σ to a set V of variables is defined by σ_{|V} (x) = σ(x) if x ∈ V and σ_{|V} (x) = x if x ∉ V. A term s is called instance of a term t if there is a substitution σ with s = σ(t) (similarly for the other syntactic constructions defined below).

A unifier of two terms s and t is a substitution σ with σ(s) = σ(t). A unifier σ is called most general (mgu) if for every other unifier σ′ there is a substitution ϕ with σ′ = ϕ ∘ σ. Most general unifiers are unique up to variable renaming. By introducing a total ordering on variables we can uniquely choose the most general unifier of two terms. A position p in a term t is represented by a sequence of natural numbers, t|_{p} denotes the subterm of t at position p, and t[s]_{p} denotes the result of replacing the subterm t|_{p} by the term s (see [8] for details).

Let → be a binary relation on a set S. Then →^{∗} denotes the transitive and reflexive closure of the relation →, and ↔^{∗} denotes the transitive, reflexive and symmetric closure of →. → is called terminating if there are no infinite chains e_{1} → e_{2} → e_{3} → · · ·. → is called confluent if for all e, e_{1}, e_{2} ∈ S with e →^{∗} e_{1} and e →^{∗} e_{2} there exists an element e_{3} ∈ S with e_{1} →^{∗} e_{3} and e_{2} →^{∗} e_{3}.

3In this paper we consider only single-sorted programs. The extension to many-sorted signatures is straightforward [39]. Since sorts are not relevant to the subject of this paper, we omit them for the sake of simplicity.

An equation s ≈ t is a multiset containing two terms s and t. Thus equations to be unified are symmetric. In order to compute with functional logic programs, we will use the equations specifying functions only in one direction. Hence we define a rewrite rule l → r as a pair of terms l, r satisfying l ∉ X and Var(r) ⊆ Var(l) where l and r are called left-hand side and right-hand side, respectively. A rewrite rule is called a variant of another rule if it is obtained by a unique replacement of variables by other variables. In the following we assume that R is a set of rewrite rules, which is also called term rewriting system.

A rewrite step is an application of a rewrite rule to a term, i.e., t →_{R} s if there exist a position p in t, a rewrite rule l → r and a substitution σ with t|_{p} = σ(l) and s = t[σ(r)]_{p}. In this case we say t is reducible (at position p). A term t is called irreducible or in normal form if there is no term s with t →_{R} s. A substitution σ is called irreducible or normalized if σ(x) is in normal form for all variables x ∈ X. A term rewriting system is (ground) confluent if the restriction of →_{R} to the set of all (ground) terms is confluent. If R is (ground) confluent and terminating, then each (ground) term t has a unique normal form which is denoted by t↓_{R}.

We are interested in proving the validity of equations. An equation s ≈ t is called valid (w.r.t. R) if s ↔_{R}^{∗} t. By Birkhoff’s Completeness Theorem, this is equivalent to the validity of s ≈ t in all models of R. In this case we also write s =_{R} t. If R is (ground) confluent and terminating, we can decide the validity of a (ground) equation s ≈ t by computing the normal form of both sides using an arbitrary sequence of rewrite steps, since s ↔_{R}^{∗} t iff s↓_{R} = t↓_{R}. In order to compute solutions to a nonground equation s ≈ t, we have to find appropriate instantiations for the variables in s and t. This can be done by narrowing. A term t is narrowable into a term t′ if there exist a nonvariable position p (i.e., t|_{p} ∉ X), a variant l → r of a rewrite rule with Var(t) ∩ Var(l) = ∅, a substitution σ such that σ is a mgu of t|_{p} and l, and t′ = σ(t[r]_{p}). In this case we write t ⇝_{[p,l→r,σ]} t′ or simply t ⇝_{σ} t′.^{4} If there is a narrowing sequence t_{1} ⇝_{σ_{1}} t_{2} ⇝_{σ_{2}} ⋯ ⇝_{σ_{n−1}} t_{n}, we write t_{1} ⇝_{σ}^{∗} t_{n} with σ = σ_{n−1} ∘ ⋯ ∘ σ_{2} ∘ σ_{1}.

Narrowing is able to solve equations w.r.t. R. For this purpose we introduce two new function symbols =^{?} and true and add the rewrite rule x =^{?} x → true to R. Then narrowing is sound and complete in the following sense.

Theorem 2.1 ([26]) Let R be a term rewriting system so that →_{R} is confluent and terminating.

1. If s =^{?} t ⇝_{σ}^{∗} true, then σ(s) =_{R} σ(t).

2. If σ′(s) =_{R} σ′(t), then there exist a narrowing derivation s =^{?} t ⇝_{σ}^{∗} true and a substitution ϕ with ϕ(σ(x)) =_{R} σ′(x) for all x ∈ Var(s) ∪ Var(t).

Since this simple narrowing procedure (enumerating all narrowing derivations) is very inefficient, several authors have proposed restrictions on the admissible narrowing derivations (see [22] for a detailed survey). For instance, Hullot [26] has introduced basic narrowing where narrowing steps in positions introduced by substitutions are forbidden. Fribourg [14] has proposed innermost narrowing where narrowing is applied only at innermost positions, and Hölldobler [25] has combined innermost and basic narrowing. Krischer and Bockmayr [29] have proposed additional tests during narrowing derivations to eliminate redundant derivations. Narrowing at outermost positions is complete only if the term rewrite system satisfies strong restrictions [11]. Lazy narrowing [6, 35, 41] is influenced by the idea of lazy evaluation in functional programming languages. Lazy narrowing steps are only applied at outermost positions with the exception that arguments are evaluated by narrowing to their head normal form if their values are required for an outermost narrowing step (see [37] for an exact definition of a lazy narrowing position). Since lazy strategies are relevant in the context of nonterminating rewrite rules, these strategies have been proved to be complete w.r.t. domain-based interpretations of rewrite rules [17, 37]. Lazy unification is very similar to lazy narrowing but manipulates sets of equations rather than terms. It has been proved to be complete for confluent and terminating term rewriting systems w.r.t. standard semantics [9, 34]. Therefore, lazy unification calculi are more appropriate in the context of terminating rewrite systems and standard semantics of equality, whereas lazy narrowing calculi are appropriate in the presence of nonterminating rules. Thus, we follow this distinction.^{5}

4Since the instantiation of the variables in the rule l → r by σ is not relevant for the computed solution of a narrowing derivation, we omit this part of σ in the example derivations in this paper.

Another improvement of simple narrowing is normalizing narrowing [13] where the term is rewritten to its normal form before a narrowing step is applied. This optimization is important since it prefers deterministic computations: rewriting a term to normal form can be done in a deterministic way since every rewriting sequence yields the same result (if R is confluent and terminating) whereas different narrowing steps may lead to different solutions and, therefore, all admissible narrowing steps must be considered. In a sequential implementation, rewriting can be efficiently implemented like reductions in functional languages whereas narrowing steps need costly backtracking management like in Prolog. For instance, if s =_{R} t, normalizing narrowing will prove the validity by a pure deterministic computation (reducing s and t to the same normal form) whereas simple narrowing would compute the normal form of s and t by costly narrowing steps. As shown in [14, 21], normalizing narrowing has the desirable effect that functional logic programs are more efficiently executable than pure logic programs.

The idea of normalizing narrowing can also be combined with other narrowing restrictions. Réty [42] has proved completeness of normalizing basic narrowing, Fribourg [14] has proposed normalizing innermost narrowing and Hölldobler [25] has combined innermost basic narrowing with normalization. Because of these advantages, normalizing narrowing is the foundation of several programming languages which combines functional and logic programming, like ALF [19], LPG [4], or SLOG [14]. However, normalization has not been included in lazy narrowing strategies.^{6} Therefore, we will show that deterministic simplification steps can be performed before nondeterministic lazy narrowing steps without destroying the completeness of lazy narrowing. The problems of integrating normalization into basic narrowing [42] shows that such a result is not obvious.

3 Ground Confluent and Terminating Programs

In this section we assume that R is a ground confluent and terminating term rewriting system. First, we present our basic lazy unification calculus to solve a system of equations. The inclusion of a normalization process will be shown in Section 3.2. The “laziness” of our calculus is in the spirit of lazy evaluation in functional programming languages, i.e., terms are evaluated only if their values are needed.

5Note that this distinction becomes essential if one considers higher-order rewrite rules [40].

6Except for [9, 12], but see the remarks in Section 1.

Lazy narrowing

f(t_{1}, …, t_{n}) ≈ t, E ⟹^{lu} t_{1} ≈ l_{1}, …, t_{n} ≈ l_{n}, r ≈ t, E

if t ∉ X or t ∈ Var(f(t_{1}, …, t_{n})) ∪ Var(E) and f(l_{1}, …, l_{n}) → r new variant of a rewrite rule

Decomposition of equations

f(t_{1}, …, t_{n}) ≈ f(t′_{1}, …, t′_{n}), E ⟹^{lu} t_{1} ≈ t′_{1}, …, t_{n} ≈ t′_{n}, E

Partial binding of variables

x ≈ f(t_{1}, …, t_{n}), E ⟹^{lu} x ≈ f(x_{1}, …, x_{n}), x_{1} ≈ ϕ(t_{1}), …, x_{n} ≈ ϕ(t_{n}), ϕ(E)

if x ∈ Var(f(t_{1}, …, t_{n})) ∪ Var(E) and ϕ = {x ↦ f(x_{1}, …, x_{n})} (where x_{i} new variable)

Figure 1: The lazy unification calculus

3.1 A Calculus for Lazy Unification

Lazy narrowing as introduced in Section 2 is defined only for constructor-based programs (see also Section 4). Since we do not require constructor-based programs in this section, we present a lazy unification calculus which is slightly more general than lazy narrowing. This lazy unification calculus manipulates sets of equations in the style of Martelli and Montanari [33] rather than terms as in narrowing calculi. Hence we define an equation system E to be a multiset of equations (in the following we write such sets without curly brackets if it is clear from the context). A solution of an equation system E is a ground substitution σ such that Var(E) ⊆ Dom(σ) and σ(s) =_{R} σ(t) for all equations s ≈ t ∈ E.^{7} An equation system E is solvable if it has at least one solution. A set S of substitutions is a complete set of solutions for E iff

1. for all σ ∈ S, σ is a solution of E;

2. for every solution θ of E, there exists some σ ∈ S with θ(x) =_{R} σ(x) for all x ∈ Var(E).

In order to compute solutions of an equation system, we transform it by the rules in Figure 1 until no more rules can be applied. The lazy narrowing transformation applies a rewrite rule to a function occurring outermost in an equation.^{8} Actually, this is not a narrowing step as defined in Section 2 since the argument terms may not be unifiable. Narrowing steps can be simulated by a sequence of transformations in the lazy unification calculus but not vice versa since our calculus also allows the application of rewrite rules to the arguments of the left-hand sides. The decomposition transformation generates equations between the argument terms of an equation if both sides have the same outermost symbol. The partial binding of variables can be applied if the variable x occurs at different positions in the equation system. In this case we instantiate the variable only with the outermost function symbol. A full instantiation by the substitution ϕ = {x ↦ f(t_{1}, …, t_{n})} may increase the computational work if x occurs several times and the evaluation of f(t_{1}, …, t_{n}) is costly. In order to avoid this problem of eager variable elimination (see [15]), we perform only a partial binding which is also called “root imitation” in [15].

7We are interested in ground solutions since later we will include inductive consequences which are valid in the ground models of R. As pointed out in [38], this ground approach subsumes the conventional narrowing approaches where also nonground solutions are taken into account (as in Theorem 2.1).

8Similarly to logic programming, we have to apply rewrite rules with fresh variables in order to ensure completeness.

It is possible to add further rules to simplify equation systems like the elimination of trivial equations:

t ≈ t, E ⟹^{lu} E

However, these rules are not really necessary and we omit them in our first approach. Later we will see how to add deterministic (failure) rules to reduce the search space of the calculus.

At first sight our lazy unification calculus has many similarities with the lazy unification rules presented in [9, 15, 34, 39]. This is not accidental since these systems have inspired us. However, there are also essential differences. Since we are interested in reducing the computational costs in the E-unification procedure, our rules behave “more lazily”. In our calculus it is allowed to evaluate a term only if its value is needed^{9} (in several positions). Otherwise, the term is left unevaluated.

Example 3.1 Consider the rewrite rule 0 ∗ x → 0. Then the only transformation sequence of the equation 0 ∗ t ≈ 0 (where t may be a costly function) is

0 ∗ t ≈ 0 ⟹^{lu} 0 ≈ 0, t ≈ x, 0 ≈ 0  (lazy narrowing)
⟹^{lu} t ≈ x, 0 ≈ 0  (decomposition)
⟹^{lu} t ≈ x  (decomposition)

Thus the term t is not evaluated since its concrete value is not needed. Consequently, we may compute solutions which are not normalized. That is a desirable property in the presence of a lazy evaluation mechanism. □

The conventional transformation rules for unification w.r.t. an empty equational theory [33] bind a variable x to a term t only if x does not occur in t. This occur check must be omitted in the presence of evaluable function symbols. Moreover, we must also instantiate occurrences of x in the term t which is done in our partial binding rule. The following example shows the necessity of these extensions.

Example 3.2 Consider the rewrite rule f(c(a)) → a. Then we can solve the equation x ≈ c(f(x)) by the following transformation sequence:

x ≈ c(f(x)) ⟹^{lu} x ≈ c(x_{1}), x_{1} ≈ f(c(x_{1}))  (partial binding)
⟹^{lu} x ≈ c(x_{1}), c(x_{1}) ≈ c(a), x_{1} ≈ a  (lazy narrowing)
⟹^{lu} x ≈ c(x_{1}), x_{1} ≈ a, x_{1} ≈ a  (decomposition)
⟹^{lu} x ≈ c(a), x_{1} ≈ a, a ≈ a  (partial binding)
⟹^{lu} x ≈ c(a), x_{1} ≈ a  (decomposition)

In fact, the initial equation is solvable and {x ↦ c(a)} is a solution of this equation. This solution is also an obvious solution of the final equation system if we disregard the auxiliary variable x_{1}. □

9Although our lazy narrowing rule is more restricted than in other lazy unification calculi, it is not optimal in the sense of [2] since we do not require strongly sequential rewrite systems.

Coalesce

x ≈ y, E ⟹^{var} x ≈ y, ϕ(E)

if x, y ∈ Var(E), x ≠ y, and ϕ = {x ↦ y}

Trivial

x ≈ x, E ⟹^{var} E

Figure 2: The variable elimination rules

In the rest of this section, we will prove soundness and completeness of our lazy unification calculus. Soundness simply means that each solution of the transformed equation system is also a solution of the initial equation system. Completeness is more difficult since we have to take into account all possible transformations. Therefore, we will show that a solvable equation system can be transformed into another very simple equation system which has “an obvious solution”. Such a final equation system is said to be in “solved form”. According to [15, 33], we call an equation x ≈ t of an equation system E solved (in E) if x is a variable which occurs neither in t nor anywhere else in E. In this case variable x is also called solved (in E). An equation system is solved or in solved form if all its equations are solved. A variable or equation is unsolved in E if it occurs in E but is not solved.

The lazy unification calculus in the present form cannot transform each solvable equation system into a solved form since equations between variables are not simplified. For instance, the equation system

x ≈ f(y), y ≈ z_{1}, y ≈ z_{2}, z_{1} ≈ z_{2}

is irreducible w.r.t. ⟹^{lu} but not in solved form since the variables y, z_{1}, z_{2} have multiple occurrences. Fortunately, this is not a problem since a solution can be extracted by merging the variables occurring in unsolved equations. Therefore, we call this system quasi-solved. An equation system is quasi-solved if each equation s ≈ t is solved or has the property s, t ∈ X. In the following we will show that a quasi-solved equation system has solutions which can be easily computed by applying the rules in Figure 2 to it. The separation between the lazy unification rules in Figure 1 and the variable elimination rules in Figure 2 has technical reasons that will become apparent later (e.g., applying variable elimination to the equation y ≈ z_{1} may not reduce the complexity measure used in our completeness proofs). However, it is obvious to extract the solutions of a quasi-solved equation system E. For this purpose we transform E by the rules in Figure 2 into a solved equation system which has a direct solution. This is justified by the following propositions.

Proposition 3.3 Let E and E′ be equation systems with E⟹^{var}E′. Then E and E′ have the same solutions.

Proof: It is obvious that E and E′ have the same solutions if the transformation rule “Trivial” is applied. In case of the rule “Coalesce”, E has the form x ≈ y, E_{0}, and E′ has the form x ≈ y, ϕ(E_{0}) with ϕ = {x ↦ y}. Let σ be a solution of E. Then σ(x) ↔_{R}^{∗} σ(y) = σ(ϕ(x)). By definition of ϕ and the congruence property of ↔_{R}^{∗}, σ(t) ↔_{R}^{∗} σ(ϕ(t)) for all terms t. Let s ≈ t ∈ E_{0}. Since σ is a solution of E, σ(s) ↔_{R}^{∗} σ(t). Moreover, σ(s) ↔_{R}^{∗} σ(ϕ(s)) and σ(t) ↔_{R}^{∗} σ(ϕ(t)) which implies σ(ϕ(s)) ↔_{R}^{∗} σ(ϕ(t)). Therefore, σ is also a solution of ϕ(E_{0}).

If σ is a solution of E′, it can be shown in a similar way that σ is also a solution of E_{0}.

Due to this proposition, the transformation ⟹^{var} preserves solutions. Moreover, it is a terminating relation:

Proposition 3.4 The relation ⟹^{var} on equation systems is terminating.

Proof: Define the complexity of an equation system as the total number of occurrences of unsolved variables in this system. Obviously, both transformation rules of ⟹^{var} reduce this number.

If an equation system is quasi-solved, we can always transform it into a solved system:

Proposition 3.5 Let E be a quasi-solved equation system. Then there exists a solved equation system E′ with E⟹^{var}^{∗}E′.

Proof: Let E be a quasi-solved equation system which is not solved. Then there exists an equation x ≈ y ∈ E which is unsolved. Hence x = y or x, y ∈ Var(E − {x ≈ y}). In the first case we apply the rule “Trivial” and in the second case we apply the rule “Coalesce”. The result of both cases is a new equation system in quasi-solved form. Since there are no infinite derivations w.r.t. ⟹^{var} (Proposition 3.4), successive transformation steps w.r.t. ⟹^{var} will end in a solved equation system.

The solutions of an equation system in solved form can be obtained as follows:

Proposition 3.6 Let E be an equation system in solved form, i.e.,

E = {x_{1} ≈ t_{1}, …, x_{n} ≈ t_{n}}

where x_{1}, …, x_{n} are different variables with x_{i} ∉ Var(t_{j}) for i, j ∈ {1, …, n} (recall that equations are multisets, thus we can write solved systems always in this form). Then the substitution set

{γ ∘ {x_{1} ↦ t_{1}, …, x_{n} ↦ t_{n}} | γ is a ground substitution with Dom(γ) = ⋃_{i=1}^{n} Var(t_{i})}

is a complete set of solutions for E.

Proof: First we show that θ : = γ∘{x_{1} ↦ t_{1}, …, x_{n} ↦ t_{n}} is a solution of E for an arbitrary ground substitution γ with Dom(γ) = ⋃_{i=1}^{n} Var(t_{i}). Clearly, Dom(θ) = {x_{1}, …, x_{n}} ∪ Dom(γ) = Var(E). Consider the equation x_{i} ≈ t_{i} ∈ E. Since x_{1}, …, x_{n} do not occur in any t_{i}, θ(x_{i}) = γ(t_{i}) = θ(t_{i}), i.e., θ is a solution of x_{i} ≈ t_{i}. Hence θ is a solution of E.

Next we show that every solution of E is covered by some substitution from the substitution set defined above. Let ξ be a solution of E. Then ξ(x_{i}) =_{R} ξ(t_{i}) for i = 1, …, n. Since ξ is a ground substitution with Var(E) ⊆ Dom(ξ), the substitution

θ : = ξ_{| ⋃_{i=1}^{n} Var(t_{i})} ∘ {x_{1} ↦ t_{1}, …, x_{n} ↦ t_{n}}

is contained in the above substitution set. We have to show ξ(x) =_{R} θ(x) for all x ∈ Var(E):

• By definition of θ and ξ, θ(x_{i}) = ξ(t_{i}) =_{R} ξ(x_{i}) for i = 1, …, n.

• If x ∈ Var(t_{j}) for some j ∈ {1, …, n}, then θ(x) = ξ(x) by definition of θ (note that x is different from any x_{i} since no x_{i} occurs in t_{j}).

Altogether, θ(x) =_{R} ξ(x) for all x ∈ Var(E).

Due to Propositions 3.3, 3.5 and 3.6, it is sufficient to transform an equation system into a quasisolved form in order to compute its solutions. Hence we can state soundness and completeness results by concentrating on quasi-solved forms. The next lemma shows the soundness if a transformation rule of the lazy unification calculus is applied.

Lemma 3.7 Let E and E′ be equation systems with E⟹^{lu}E′. Then each solution σ of E′ is also a solution of E.

Proof: Assume that E⟹^{lu}E′ and σ is a solution of E′. Clearly, Var(E) ⊆ Dom(σ) since Var(E) ⊆ Var(E′) ⊆ Dom(σ). There are three cases corresponding to the applied transformation rule:

1. The lazy narrowing rule has been applied. Then E = f(t_{1}, …, t_{n}) ≈ t, E_{0}, f(l_{1}, …, l_{n}) → r is a variant of a rewrite rule and E′ = t_{1} ≈ l_{1}, …, t_{n} ≈ l_{n}, r ≈ t, E_{0}. Since σ is a solution of E′, σ(t_{i}) ↔_{R}^{∗} σ(l_{i}) (for i = 1, …, n) and σ(r) ↔_{R}^{∗} σ(t). These equivalences imply σ(f(t_{1}, …, t_{n})) ↔_{R}^{∗} σ(f(l_{1}, …, l_{n})) by the congruence property of ↔_{R}^{∗}. Since f(l_{1}, …, l_{n}) → r is a variant of a rewrite rule, σ(f(l_{1}, …, l_{n})) →_{R} σ(r) ↔_{R}^{∗} σ(t). Hence σ(f(t_{1}, …, t_{n})) ↔_{R}^{∗} σ(t), i.e., σ is a solution of E.

2. The decomposition rule has been applied. Then E = f(t_{1}, …, t_{n}) ≈ f(t′_{1}, …, t′_{n}), E_{0} and E′ = t_{1} ≈ t′_{1}, …, t_{n} ≈ t′_{n}, E_{0}. Since σ is a solution of E′, σ(t_{i}) ↔_{R}^{∗} σ(t′_{i}) (for i = 1, …, n). Hence σ(f(t_{1}, …, t_{n})) ↔_{R}^{∗} σ(f(t′_{1}, …, t′_{n})) by the congruence property of ↔_{R}^{∗}.

3. The partial binding rule has been applied. Then E = x ≈ f(t_{1}, …, t_{n}), E_{0} and E′ = x ≈ f(x_{1}, …, x_{n}), x_{1} ≈ ϕ(t_{1}), …, x_{n} ≈ ϕ(t_{n}), ϕ(E_{0}) where ϕ = {x ↦ f(x_{1}, …, x_{n})}. Since σ is a solution of E′, we have

(a) σ(x) ↔_{R}^{∗} σ(f(x_{1}, …, x_{n}))

(b) σ(x_{i}) ↔_{R}^{∗} σ(ϕ(t_{i})) (for i = 1, …, n)

(c) σ solution of ϕ(E_{0})

By definition of ϕ, (a) and the congruence property of ↔_{R}^{∗},

σ(ϕ(t)) ↔_{R}^{∗} σ(t) for all terms t  (∗)

Hence σ is also a solution of E_{0}. Moreover,

σ(x) ↔_{R}^{∗} σ(f(x_{1}, …, x_{n}))  (by (a))
↔_{R}^{∗} σ(f(ϕ(t_{1}), …, ϕ(t_{n}))) (by (b))
↔_{R}^{∗} σ(f(t_{1}, …, t_{n}))  (by (∗))

Hence σ is a solution of x ≈ f(t_{1}, …, t_{n}).

The following soundness theorem can be proved by a simple induction on the transformation steps using the previous lemma.

Theorem 3.8 Let E and E′ be equation systems with E⟹^{lu}^{∗}E′. Then each solution σ of E′ is a solution of E.

The completeness proof is more difficult since we have to consider all possible transformation sequences. Therefore, we show that for each solution of an equation system there is a derivation into a quasi-solved form that has the same solution. Note that the solution of the quasi-solved form cannot be identical to the required solution, because new additional variables are generated during the derivation (by lazy narrowing and partial binding transformations). However, this is not a problem since we are interested in solutions w.r.t. the variables of the initial equation system.

Theorem 3.9 Let E be a solvable equation system with solution σ. Then there exists a derivation E⟹^{lu}^{∗}E′ with E′ in quasi-solved form such that E′ has a solution σ′ with σ′(x) =_{R} σ(x) for all x ∈ Var(E).

Proof: We show the existence of a derivation from E into a quasi-solved equation system by the following steps:

1. We define a reduction relation ⇒ on pairs of the form (σ, E), where E is an equation system and σ is a solution of E, with the property that (σ, E) ⇒ (σ′, E′) implies E⟹^{lu}E′ and σ′(x) = σ(x) for all x ∈ Var(E).

2. We define a terminating ordering ≻ on these pairs.

3. We show: If E has a solution σ but E is not in quasi-solved form, then there exists a pair (σ′, E′) with (σ, E) ⇒ (σ′, E′) and (σ, E) ≻ (σ′, E′).

2 and 3 implies that each solvable equation system can be transformed into a quasi-solved form. By 1, the solution of this quasi-solved form is the required solution of the initial equation system.

In the sequel we will show 1 and 3 in parallel. First we define the terminating ordering ≻. For this purpose we use the strict subterm ordering ≻_{sst} on terms defined by t ≻_{sst} s iff there is a position p in t with t|_{p} = s ≠ t. Since R is a terminating rewrite system, the relation →_{R} on terms is also terminating. Let ≻≻ be the transitive closure of the relation →_{R} ∪ ≻_{sst}. Then ≻≻ is also terminating [28].^{10} Now we define the following ordering on pairs (σ, E): (σ, E) ≻ (σ′, E′) iff

{σ(s), σ(t) | s ≈ t ∈ E is unsolved in E} ≻≻_{mul} {σ′(s′), σ′(t′) | s′ ≈ t′ ∈ E′ is unsolved in E′} (∗)

where ≻≻_{mul} is the multiset extension^{11} of the ordering ≻≻ (all sets in this definition are multisets). ≻≻_{mul} is terminating (note that all multisets considered here are finite) since ≻≻ is terminating [7].

10Note that the use of the relation →_{R} instead of ≻ ≻ (as done in [9]) is not sufficient for the completeness proof since →_{R} has not the subterm property [7] in general.

11The multiset ordering ≻ ≻_{mul} is the transitive closure of the replacement of an element by a finite number of elements that are smaller w.r.t. ≻ ≻ [7].

Now we will show that we can apply a transformation step to a solvable but unsolved equation system such that its complexity is reduced. Let E be an equation system not in quasi-solved form and σ be a solution of E. Since E is not quasi-solved, there must be an equation which has one of the following forms:

1. There is an equation E = s ≈ t, E_{0} with s, t ∉ X: Let s = f(s_{1}, …, s_{n}) with n ≥ 0 (the other case is symmetric). Consider an innermost derivation of the normal forms of σ(s) and σ(t):

(a) No rewrite step is performed at the root of σ(s) and σ(t): Then t has the form t = f(t_{1}, …, t_{n}) and σ(s)↓_{R} = σ(t)↓_{R} = f(u_{1}, …, u_{n}). Since σ(s) and σ(t) are not reduced at the root, σ(s_{i})↓_{R} = u_{i} = σ(t_{i})↓_{R} for i = 1, …, n. Now we apply the decomposition transformation and obtain the equation system

E′ = s_{1} ≈ t_{1}, …, s_{n} ≈ t_{n}, E_{0}

Obviously, σ is a solution of E′. Moreover, the complexity of the new equation system is reduced because the equation s ≈ t is unsolved in E and each σ(s_{i}) and σ(t_{i}) is smaller than σ(s) and σ(t), respectively, since ≻≻ contains the strict subterm ordering ≻_{sst}. Hence (σ, E) ≻ (σ, E′).

(b) A rewrite step is performed at the root of σ(s), i.e., the innermost rewriting sequence of σ(s) has the form

σ(s) →_{R}^{∗} f(s′_{1}, …, s′_{1}) →_{R} θ(r) →_{R}^{∗} σ(s)↓_{R}

where f(l_{1}, …, l_{n}) → r is a new variant of a rewrite rule, θ(l_{i}) = s′_{i} and σ(s_{i}) →_{R}^{∗} s′_{i} for i = 1, …, n. An application of the lazy narrowing transformation yields the equation system

E′ = s_{1} ≈ l_{1}, …, s_{n} ≈ l_{n}, r ≈ t, E_{0}

We combine σ and θ to a new substitution σ′ = σ ∪ θ (this is always possible since θ does only work on the variables of the new variant of the rewrite rule). Note that Var(E′) ⊆ Dom(σ′). σ′ is a solution of E′ since

σ′(s_{i}) = σ(s_{i}) →_{R}^{∗} s′_{i} = θ(l_{i}) = σ′(l_{i})

and

σ′(r) = θ(r) →_{R}^{∗} σ(s)↓_{R} ↔_{R}^{∗} σ(t) = σ′(t)

Since the transitive closure of →_{R} is contained in ≻≻, σ(s_{i}) ≻≻ σ′(l_{i}) (if σ(s_{i}) ≠ σ′(l_{i})) and σ(s) ≻≻ σ′(r). Since s ≈ t is unsolved in E, the term σ(s) is contained in the left multiset of the ordering definition (∗), and it is replaced by a selection of the smaller terms σ(s_{1}), …, σ(s_{n}), σ′(l_{1}), …, σ′(l_{n}), σ′(r) (σ(s) ≻≻ σ(s_{i}) since ≻≻ contains the strict subterm ordering). Therefore, the new equation system is smaller w.r.t. ≻, i.e., (σ, E) ≻ (σ′, E′).

2. There is an equation E = x ≈ t, E_{0} with t = f(t_{1}, …, t_{n}) and x unsolved in E: Hence x ∈ Var(t) ∪ Var(E_{0}). Again, we consider an innermost derivation of the normal form of σ(t):

(a) A rewrite step is performed at the root of σ(t). Then we apply a lazy narrowing step and proceed as in the previous case.

(b) No rewrite step is performed at the root of σ(t), i.e., σ(t)↓_{R} = f(t′_{1}, …, t′_{n}) and σ(t_{i})↓_{R} = t′_{i} for i = 1, …, n. We apply the partial binding transformation and obtain the equation system

E′ = x ≈ f(x_{1}, …, x_{n}), x_{1} ≈ ϕ(t_{1}), …, x_{n} ≈ ϕ(t_{n}), ϕ(E_{0})

where ϕ = {x ↦ f(x_{1}, …, x_{n})} and x_{i} are new variables. We extend σ to a substitution σ′ by adding the bindings σ′(x_{i}) = t′_{i} for i = 1, …, n, i.e., Var(E′) ⊆ Dom(σ′). Then

σ′(f(x_{1}, …, x_{n})) = f(t′_{1}, …, t′_{n}) = σ(t)↓_{R} ↔_{R}^{∗} σ(t) ↔_{R}^{∗} σ(x) = σ′(x)

Moreover, σ′(ϕ(x)) = σ′(x)↓_{R} which implies σ′(s) ↔_{R}^{∗} σ′(ϕ(s)) for all terms s. Hence σ′(ϕ(t_{i})) ↔_{R}^{∗} σ′(t_{i}) ↔_{R}^{∗} t′_{i} = σ′(x_{i}). Altogether, σ′ is a solution of E′. It remains to show that this transformation reduces the complexity of the equation system. Since σ′(ϕ(x)) = σ(x)↓_{R}, we have σ(x) →_{R}^{∗} σ′(ϕ(x)). Hence σ(E_{0}) is equal to σ′(ϕ(E_{0})) (if σ(x) = σ′(ϕ(x))) or σ′(ϕ(E_{0})) is smaller w.r.t. ≻≻_{mul}. Therefore, it remains to check that σ(t) is greater than each σ′(x_{1}), …, σ′(x_{n}), σ′(ϕ(t_{1})), …, σ′(ϕ(t_{n})) w.r.t. ≻≻ (note that the equation x ≈ t is unsolved in E, but the equation x ≈ f(x_{1}, …, x_{n}) is solved in E′). First of all, σ(t) ≻≻ σ(t_{i}) since ≻≻ includes the strict subterm ordering. Moreover, σ(t_{i}) →_{R}^{∗} σ′(x_{i}), i.e., σ′(x_{i}) is equal or smaller than σ(t_{i}) w.r.t. ≻≻ for i = 1, …, n. This implies σ(t) ≻≻ σ′(x_{i}). Similarly, σ′(ϕ(t_{i})) is equal or smaller than σ(t_{i}) w.r.t. ≻≻ since σ′(ϕ(x)) = σ(x)↓_{R}. Thus σ(t) ≻≻ σ′(ϕ(t_{i})). Altogether, (σ, E) ≻ (σ′, E′).

We want to point out that there exist also other orderings on substitution/equation system pairs to prove the completeness of our calculus. However, the ordering chosen above is tailored to a simple proof for the completeness of lazy unification with simplification as we will see in the next section.

Propositions 3.3, 3.5, 3.6 and Theorems 3.8 and 3.9 imply that a complete set of solutions for a given equation system E can be computed by enumerating all derivations in the lazy unification calculus from E into a quasi-solved equation system. Due to the nondeterminism in the lazy unification calculus, there are many unsuccessful and often infinite derivations. Therefore, we will show in the next section how to reduce this nondeterminism by integrating a deterministic simplification process into the lazy unification calculus. More determinism can be achieved by dividing the set of function symbols into constructors and defined functions. This will be the subject of Section 3.3.

3.2 Integrating Simplification Into Lazy Unification

The lazy unification calculus admits a high degree of nondeterminism even if there is only one reasonable derivation. This is due to the fact that functional expressions are processed “too lazy”.

Example 3.10 Consider the rewrite rules

\begin{matrix}f(a) → & c & g(a) → & a \\ f(b) → & d & g(b) → & b \end{matrix}

and the equation f(g(b)) ≈ d. Then there are the following four different derivations in our lazy unification calculus:

\begin{matrix}f(g(b)) ≈ d & ⟹^{lu} & g(b) ≈ a, c ≈ d & ⟹^{lu} & b ≈ a, a ≈ a, c ≈ d & ⟹^{lu} & b ≈ a, c ≈ d \\ f(g(b)) ≈ d & ⟹^{lu} & g(b) ≈ a, c ≈ d & ⟹^{lu} & b ≈ b, b ≈ a, c ≈ d & ⟹^{lu} & b ≈ a, c ≈ d \\ f(g(b)) ≈ d & ⟹^{lu} & g(b) ≈ b, d ≈ d & ⟹^{lu} & b ≈ a, a ≈ b, d ≈ d & ⟹^{lu} & b ≈ a, a ≈ b \\ f(g(b)) ≈ d & ⟹^{lu} & g(b) ≈ b, d ≈ d & ⟹^{lu} & b ≈ b, b ≈ b, d ≈ d & ⟹^{lu}^{∗} & ∅ \end{matrix}

The first three derivations do not end in a quasi-solved form, only the last derivation is successful. However, if we first compute the normal form of f(g(b)), which is d, then there is only one possible derivation: d ≈ d ⟹^{lu} ∅. Hence we will show that the lazy unification calculus remains to be sound and complete if the (deterministic!) normalization of terms is included. □

It is well-known [14, 21] that the inclusion of inductive consequences for normalization may have an essential effect on the search space reduction in normalizing narrowing strategies. Therefore, we will also allow the use of additional inductive consequences for normalization. A rewrite rule l → r is called inductive consequence (of R) if σ(l) =_{R} σ(r) for all ground substitutions σ with Dom(σ) = Var(l). For instance, the rule x + 0 → x is an inductive consequence of the term rewriting system

\begin{matrix}0 + y → & y \\ s(x) + y → & s(x + y) \end{matrix}

If we want to solve the equation s(x)+0 ≈ s(x), our basic lazy unification calculus would enumerate the solutions {x ↦ 0}, {x ↦ s(0)}, {x ↦ s(s(0))}, and so on, i.e., this equation has an infinite search space. Using the inductive consequence x+0 → x for normalization, the equation s(x)+0 ≈ s(x) is reduced to s(x) ≈ s(x) and then transformed into the quasi-solved form x ≈ x representing the solution set where x is replaced by any ground term.^{12}

In the following, we assume that I is a set of inductive consequences of R (the set of simplification rules) so that the rewrite relation →_{I} is terminating. We will use rules from R for lazy narrowing and rules from I for simplification. Note that each rule from R is also an inductive consequence and can be included in I. However, we do not require that all rules from R must be used for normalization. This is reasonable if there are duplicating rules where one variable of the left-hand side occurs several times on the right-hand side, like f(x) → g(x, x). If we normalize the equation f(s) ≈ t with this rule, then the term s is duplicated. This may increase the computational costs if the evaluation of s is necessary and costly. In such a case it would be better to use this rule only in lazy narrowing steps.

In order to include simplification into the lazy unification calculus, we define a relation ⇒_{I} on systems of equations. s ≈ t ⇒_{I} s′ ≈ t′ iff s′ and t′ are normal forms of s and t w.r.t. →_{I}, respectively. E ⇒_{I} E′ iff E = e_{1}, …, e_{n} and E′ = e′_{1}, …, e′_{n} where e_{i} ⇒_{I} e′_{i} for i = 1, …, n. Note that ⇒_{I} describes a deterministic computation process.^{13} E⟹^{lus}E′ is a derivation step in the lazy unification calculus with simplification if E ⇒_{I} \overline{E}⟹^{lu}E′ for some \overline{E}.

12In larger single-sorted term rewriting systems, it can be difficult to find inductive consequences. E.g., x + 0 → x is not an inductive consequence if there is a constant a since a + 0 =_{R} a is not valid. However, in practice specifications are many-sorted and then inductive consequences must be valid only for all well-sorted ground substitutions.

Therefore, we want to point out that all results in this paper can also be extended to many-sorted term rewriting systems in a straightforward way.

The following lemma shows the soundness of one rewrite step with a simplification rule. The formulation of soundness differs from Lemma 3.7 since we have to consider the fact that goal variables may be deleted by normalization.

Lemma 3.11 Let s ≈ t be an equation, s →_{I} s′ be a rewrite step, and σ′ be a solution of s′ ≈ t. Then any ground substitution σ with Var(s ≈ t) ⊆ Dom(σ) and σ(x) =_{R} σ′(x) for all x ∈ Var(s′ ≈ t) is a solution of s ≈ t.

Proof: Let s →_{I} s′ and σ′ be a solution of s′ ≈ t, i.e., σ(s′) =_{R} σ(t). We consider a ground substitution σ with Var(s ≈ t) ⊆ Dom(σ) and σ(x) =_{R} σ′(x) for all x ∈ Var(s′ ≈ t). Obviously, σ(s) →_{I} σ(s′) using the same rewrite rule from I. Hence σ(s) =_{R} σ(s′) since I consists of inductive consequences of R and σ(s) and σ(s′) are ground terms. By σ(s′) =_{R} σ(t), this implies σ(s) =_{R} σ(t), i.e., σ is a solution of s ≈ t.

Now we can state the soundness of the calculus ⟹^{lus}:

Theorem 3.12 Let E and E′ be equation systems with E⟹^{lus}^{∗}E′ where E′ is in quasi-solved form, and σ′ be a solution of E′. Then any ground substitution σ with Var(E) ⊆ Dom(σ) and σ(x) =_{R} σ′(x) for all x ∈ Var(E′) is a solution of E.

Proof: By Lemma 3.11, we can show the soundness of ⇒_{I} with a simple induction on the sequence of rewrite steps. Combining this result with Lemma 3.7 shows the soundness of one ⟹^{lus} step. Then the theorem follows by another simple induction on the number of ⟹^{lus} steps.

For the completeness proof we have to show that solutions are not lost by the application of simplification rules:

Lemma 3.13 Let E be an equation system and σ be a solution of E. If E ⇒_{I} E′, then σ is a solution of E′.

Proof: By definition of rewrite rules, Var(E′) ⊆ Var(E). Let s ≈ t ∈ E, σ(s) =_{R} σ(t) and s ≈ t ⇒_{I} s′ ≈ t′. Hence s →_{I}^{∗} s′ and t →_{I}^{∗} t′ which implies σ(s) →_{I}^{∗} σ(s′) and σ(t) →_{I}^{∗} σ(t′). Since σ is a ground substitution with Var(E) ⊆ Dom(σ) and I are inductive consequences, σ(s) =_{R} σ(s′) and σ(t) =_{R} σ(t′). Hence σ(s′) =_{R} σ(t′), i.e., σ is a solution of all equations in E′.

The last lemma would imply the completeness of the calculus ⟹^{lus} if a derivation step with ⇒_{I} does not increase the ordering used in the proof of Theorem 3.9. Unfortunately, this is not the case in general since the termination of →_{R} and →_{I} may be based on different orderings (e.g., R = {a → b} and I = {b → a}). In order to avoid such problems, we require that the relation →_{R∪I} is terminating which is not a real restriction in practice.

13If there exist more than one normal form w.r.t. →_{I}, it is sufficient to select don’t care one of these normal forms.

Theorem 3.14 Let I be a set of inductive consequences of the ground confluent and terminating rewrite system R such that →_{R∪I} is terminating. Let E be a solvable equation system with solution σ. Then there exists a derivation E ⟹^{lus}^{∗} E′ such that E′ is in quasi-solved form and has a solution σ′ with σ′(x) =_{R} σ(x) for all x ∈ Var(E).

Proof: In the proof of Theorem 3.9, we have shown how to apply a transformation step to an equation system not in quasi-solved form such that the solution is preserved. We can use the same proof for the transformation ⟹^{lus} since Lemma 3.13 shows that normalization steps preserve solutions. The only difference concerns the ordering where we use →_{R∪I} instead of →_{R}, i.e., ≻≻ is now defined to be the transitive closure of the relation →_{R∪I} ∪ ≻_{sst}. Clearly, this does not change anything in the proof of Theorem 3.9. Moreover, the relation ⇒_{I} does not increase the complexity w.r.t. this ordering but reduces it if simplification rules are applied since →_{I} is contained in ≻≻.

Theorems 3.12 and 3.14 show that we can integrate the deterministic simplification process into the lazy unification calculus without loosing soundness and completeness. Note that the rules from I can only be applied if their left-hand sides can be matched with a subterm of the current equation system. If these subterms are not sufficiently instantiated, the rewrite rules are not applicable and hence we loose potential determinism in the unification process.

Example 3.15 Consider the rules

\begin{matrix}zero(s(x)) → & zero(x) \\ zero(0) → & 0 \end{matrix}

(assume that these rules are contained in R as well as in I) and the equation system zero(x) ≈ 0, x ≈ 0. Then there exists the following derivation in our calculus (this derivation is also possible in the unification calculi in [15, 34]):

zero(x) ≈ 0, x ≈ 0

⟹^{lus} x ≈ s(x_{1}), zero(x_{1}) ≈ 0, x ≈ 0  (lazy narrowing with first rule)
⟹^{lus} x ≈ s(x_{1}), x_{1} ≈ s(x_{2}), zero(x_{2}) ≈ 0, x ≈ 0  (lazy narrowing with first rule)
⟹^{lus} x ≈ s(x_{1}), x_{1} ≈ s(x_{2}), x_{2} ≈ s(x_{3}), zero(x_{3}) ≈ 0, x ≈ 0 (lazy narrowing with first rule)
⟹^{lus} ⋯

This infinite derivation could be avoided if we apply the partial binding rule in the first step:

zero(x) ≈ 0, x ≈ 0 ⟹^{lus} zero(0) ≈ 0, x ≈ 0  (partial binding)
⇒_{I} 0 ≈ 0, x ≈ 0  (rewriting with second rule)
⟹^{lus} x ≈ 0  (decomposition)

In the next section we will present an optimization which prefers the latter derivation and avoids the first infinite derivation. □

3.3 Constructor-based Systems

In most existing functional logic programming languages, a distinction is made between operation symbols to construct data terms, called constructors, and operation symbols to operate on data Decomposition of constructor equations

c(t_{1}, …, t_{n}) ≈ c(t′_{1}, …, t′_{n}), E ⟹^{luc} t_{1} ≈ t′_{1}, …, t_{n} ≈ t′_{n}, E

if c ∈ C

Full binding of variables to ground constructor terms

x ≈ t, E ⟹^{luc} x ≈ t, ϕ(E)

if x ∈ Var(E), t ∈ T (C, ∅) and ϕ = {x ↦ t}

Partial binding of variables to constructor terms

x ≈ c(t_{1}, …, t_{n}), E ⟹^{luc} x ≈ c(x_{1}, …, x_{n}), x_{1} ≈ ϕ(t_{1}), …, x_{n} ≈ ϕ(t_{n}), ϕ(E)

if c ∈ C, x ∈ Var(c(t_{1}, …, t_{n})) ∪ Var(E), x ∉ cvar(c(t_{1}, …, t_{n})) and ϕ = {x ↦ c(x_{1}, …, x_{n})} (x_{i} new variable)

Figure 3: Deterministic transformations for constructor-based rewrite systems

terms, called defined functions or operations (see, for instance, the functional logic languages ALF [19], BABEL [37], K-LEAF [17], SLOG [14], or the RAP system [16]). Such a distinction allows to optimize our unification calculus. Therefore, we assume in this section that the signature F is divided into two sets F = C ∪ D, called constructors and defined functions, with C ∩ D = ∅. A constructor term t is built from constructors and variables, i.e., t ∈ T (C, X). The distinction between constructors and defined functions comes with the restriction that for all rewrite rules l → r the outermost symbol of l is always a defined function.^{14}

A basic property of such constructor-based term rewriting systems is the irreducibility of constructor terms. Due to this fact, we can specialize the rules of our basic lazy unification calculus. Therefore, we define the deterministic transformations in Figure 3. Deterministic transformations are intended to be applied as long as possible before any transformation ⟹^{lu} is used. Hence they can be integrated into the deterministic normalization process ⇒_{I}. It is obvious that this modification preserves soundness and completeness. The decomposition transformation for constructor equations must be applied in any case in order to obtain a quasi-solved equation system since a lazy narrowing step R cannot be applied to constructor equations. The full binding of variables to ground constructor terms is an optimization which combines subsequent applications of partial binding transformations. This transformation decreases the complexity used in the proof of Theorem 3.14 since a constructor term is always in normal form. The partial binding transformation for constructor terms performs an eager (partial) binding of variables to constructor terms since a lazy narrowing step cannot be applied to the constructor term. Moreover, this binding transformation is combined with an occur check since it cannot be applied if x ∈ cvar(c(t_{1}, …, t_{n})) where cvar Clash of constructor equations

14In constructor-based systems, it is often required that all rules have the form f(t_{1}, …, t_{n}) → r with f ∈ D and t_{1}, …, t_{n} ∈ T (C, X). However, this stronger requirement is not necessary for the results in this section.

c(t_{1}, …, t_{n}) ≈ d(t′_{1}, …, t′_{m}), E ⟹^{luc} fail

if c, d ∈ C and c ≠ d

Occur check

x ≈ c(t_{1}, …, t_{n}), E ⟹^{luc} fail

if x ∈ cvar(c(t_{1}, …, t_{n}))

Figure 4: Failure rules for constructor-based rewrite systems

denotes the set of all variables occurring outside terms headed by defined function symbols:

cvar(x) = {x}
cvar(c(t_{1}, …, t_{n})) = ⋃_{i=1}^{n} cvar(t_{i}) if c ∈ C
cvar(f(t_{1}, …, t_{n})) = ∅  if f ∈ D

This restriction avoids infinite derivations of the following kind:

x ≈ c(x) ⟹^{lu} x ≈ c(x_{1}), x_{1} ≈ c(x_{1})  (partial binding)
⟹^{lu} x ≈ c(x_{1}), x_{1} ≈ c(x_{2}), x_{2} ≈ c(x_{2})  (partial binding)
⟹^{lu} ⋯

It is obvious that an equation of the form x ≈ c(t_{1}, …, t_{n}) with x ∈ cvar(c(t_{1}, …, t_{n})) is unsolvable.

A further optimization can be added if all functions are reducible on ground constructor terms, i.e., for all f ∈ D and t_{1}, …, t_{n} ∈ T (C, ∅) there exists a term t with f(t_{1}, …, t_{n}) →_{R} t. In this case all ground terms have a ground constructor normal form and the partial binding transformation of ⟹^{lu} can be completely omitted which increases the determinism in the lazy unification calculus.

If we invert the deterministic transformation rules, we obtain a set of failure rules shown in Figure 4. Failure rules are intended to be tried during the deterministic transformations. If a failure rule is applicable, the derivation can be safely terminated since the equation system cannot be transformed into a quasi-solved system.

3.4 Using Inductive Consequences

In Section 5 we will discuss the advantages of using program rules for simplification between lazy narrowing or unification steps for various classes of functional logic programs. Therefore, we provide in this section only an example which demonstrates the advantages of using inductive consequences for simplification in our lazy unification calculus. Since inductive consequences are only used for simplification, they do not increase the search space. Formally, this is confirmed by the fact that lazy unification derivations correspond to rewrite derivations (Lemma 3.7) and the application of inductive consequences reduces the complexity of goals (Theorem 3.14).

Example 3.16 Consider the following rewrite rules for addition and multiplication on natural numbers where C = {0, s} are constructors and D = {+, ∗} are defined functions:

\begin{matrix}0 + y → & y & (R_{1}) & 0 ∗ y → & 0 & (R_{3}) \\ s(x) + y → & s(x + y) & (R_{2}) & s(x) ∗ y → & y + x ∗ y & (R_{4}) \end{matrix}

If we use this confluent and terminating set of rewrite rules for lazy narrowing (R) as well as for normalization (I) and add the inductive consequence x ∗ 0 → 0 to I, then our lazy unification calculus with simplification has a finite search space for the equation x ∗ y ≈ s(0). This is due to the fact that the following derivation can be terminated using the inductive consequence and the clash rule:

x ∗ y = s(0) ⟹^{lu} x ≈ s(x_{1}), y ≈ y_{1}, y_{1} + x_{1} ∗ y_{1} ≈ s(0)  (lazy narrowing, R_{4})
⟹^{lu} x ≈ s(x_{1}), y ≈ y_{1}, y_{1} ≈ 0, x_{1} ∗ y_{1} ≈ y_{2}, y_{2} ≈ s(0) (lazy narrowing, R_{1})
⟹^{luc} x ≈ s(x_{1}), y ≈ 0, y_{1} ≈ 0, x_{1} ∗ 0 ≈ y_{2}, y_{2} ≈ s(0)  (bind variable y_{1})
⟹^{luc} x ≈ s(x_{1}), y ≈ 0, y_{1} ≈ 0, x_{1} ∗ 0 ≈ s(0), y_{2} ≈ s(0) (bind variable y_{2})
⇒_{I} x ≈ s(x_{1}), y ≈ 0, y_{1} ≈ 0, 0 ≈ s(0), y_{2} ≈ s(0)  (reduce x_{1} ∗ 0)
⟹^{luc} fail  (clash between 0 and s)

The equation x_{1} ∗ 0 ≈ s(0) could not be transformed into the equation 0 ≈ s(0) without the inductive consequence. Consequently, an infinite derivation would occur in our basic unification calculus of Section 3.1.

Note that other lazy unification calculi [15, 34] or lazy narrowing calculi [37, 41] have an infinite search space for this equation. It is also interesting to note that a normalizing innermost narrowing strategy as in [14, 20] has also an infinite search space even if the same simplification rules are available. This shows the advantage of combining a lazy strategy with simplification. □

4 Rewrite Systems with Nonterminating Rules

In this section we consider rewrite systems which are not necessarily terminating. Similarly to lazy evaluation in functional languages, lazy narrowing has at least two advantages in comparison to other (eager) narrowing strategies:

1. Since lazy narrowing applies narrowing steps at inner positions only if it is demanded by some rule, useless narrowing steps (steps at inner positions which do not contribute to the result) are avoided.^{15}

2. Since lazy narrowing evaluates functions only if their results are demanded, it can deal with nonterminating functions and infinite data structures. Other narrowing strategies (like basic, innermost, or outermost narrowing) require a terminating set of rewrite rules and cannot deal with infinite data structures.

The next example should emphasize the latter point.

15To be precise, the avoidance of useless narrowing steps depends on the lazy narrowing strategy. Although this is one of the motivations of all lazy strategies, the only strategy for which this property has been formally proved is needed narrowing [2].

Example 4.1 The following rules define a function from(n), which computes an infinite list of naturals starting from n, and a function first(n, l), which computes the first n elements of the list l ([] denotes the empty list and [e|l] denotes a nonempty list with first element e and tail l):

\begin{matrix}from(n) → & [n|from(s(n))] \\ first(0, l) → & [] \\ first(s(n), [e|l]) → & [e|first(n, l)] \end{matrix}

The first rule of this rewrite system is nonterminating. Lazy evaluation of the expression first(s(s(0)), from(0)) yields the result [0, s(0)], whereas an eager evaluation does not terminate due to the nonterminating eager evaluation of from(0). Similarly, lazy narrowing applied to the equation first(x, from(y)) ≈ [0, s(0)] computes the solution {x ↦ s(s(0)), y ↦ 0}, whereas an eager narrowing strategy runs into an infinite loop. □

Since narrowing applies rules only in one direction from left to right, the confluence of the rewrite relation is an essential requirement for the completeness of all narrowing strategies. However, confluence is an undecidable property of a rewrite system if it is not terminating. Therefore, functional logic languages with nonterminating rewrite systems have the following requirements on rewrite rules:

1. Constructor-based: The signature F is divided into two disjoint sets C and D, called constructors and defined functions. Moreover, if l → r is a rewrite rule, then l has the form f(t_{1}, …, t_{n}) with f ∈ D and t_{1}, …, t_{n} ∈ T (C, X).

2. Left-linearity: All rules are left-linear, i.e., no variable appears more than once in the left-hand side of any rule.

3. Nonambiguity: If l_{1} → r_{1} and l_{2} → r_{2} are two different rules, then l_{1} and l_{2} are not unifiable (strong nonambiguity), or if l_{1} and l_{2} have a most general unifier σ, then σ(r_{1}) and σ(r_{2}) are identical (weak nonambiguity).

Rewrite systems with these properties are called constructor-based (weakly) orthogonal systems. These conditions ensure the uniqueness of normal forms if they exist. Due to the presence of nonterminating functions, the completeness results for lazy strategies are stated with respect to domain-based interpretations of rewrite rules [17, 37]. In particular, the equality of two expressions holds only if both sides are reducible to the same ground constructor term. The completeness of lazy narrowing w.r.t. this semantics is formally stated in [37]. We will show that deterministic simplification steps can be included in lazy narrowing derivations without destroying completeness for such rewrite systems, i.e., we assume that R is a constructor-based weakly orthogonal term rewriting system.

Loogen and Winkler [32] have shown how to increase deterministic computations in the implementation of such programs: if no goal variable has been bound in a narrowing step, then all attempts to apply alternative rules at the same position can be ignored due to the nonambiguity of the rules. In this case a “cut” can be executed to eliminate the choice point for alternative rules. Since the execution of this “cut” depends on the run-time behavior of the program (whether or not a goal variable has been bound during unification), it is called dynamic cut in [32]. The dynamic cut can be implemented by a special POP instruction which checks whether a goal variable has been bound during unification and, if this did not happen, removes the last choice point. The advantage of this method is its simple implementation, but it has also two disadvantages:

1. The dynamic cut removes choice points which have been created but are not needed in the further computation process. Hence it does not avoid the creation of choice points (one of the most expensive operations in the implementation of logic languages): if a choice point is not needed in a deterministic computation, it is created and then deleted after the unification of the rule’s left-hand side.

2. The detection of deterministic computations depends on the order of the rules. If a rule which enables a deterministic computation step is not at the beginning, nondeterministic steps may be performed even if a deterministic step is possible.

The following example discusses the second disadvantage in more detail.

Example 4.2 Consider the rules of Example 1.2 and the goal equation 0 ∗ one(x) ≈ 0. Using the dynamic cut technique, first a choice point for the rules R_{3} and R_{4} is created, rule R_{3} is applied to narrow the left-hand side yielding the trivial equation 0 ≈ 0, and then the choice point is removed since no goal variable (x) has been bound in the narrowing step (dynamic cut). Hence the attempt to apply rule R_{4} is avoided by the dynamic cut. However, if we try to solve the equation one(x) ∗ 0 ≈ 0, the dynamic cut has no effect. As before, first a choice point for the rules R_{3} and R_{4} is created, then an attempt to apply rule R_{3} is made.^{16} Since it is necessary to evaluate the first argument in order to decide the applicability of this rule, one(x) is a lazy narrowing redex which is evaluated by applying rules R_{5} or R_{6} (this evaluation has an infinite search space and does not terminate in a sequential implementation, cf. Example 1.2). In any case the goal variable x will be bound and therefore the dynamic cut has no effect. □

Although the dynamic cut has some disadvantages since it is applied after a narrowing attempt, the nonambiguity of the rules is the key to exploit deterministic computations in functional logic programs. In the following we will show that we can apply deterministic rewrite steps before a narrowing step. This technique avoids the creation of superfluous choice points and is independent on the order of rules (if we use all rules also for rewrite steps).

The next lemma is due to Loogen and Winkler [32] and shows that it is not necessary to consider alternative rules for narrowing if one rule is applicable without binding goal variables. This is a consequence of the nonambiguity condition on rewrite rules.

Lemma 4.3 Let R_{1} = l_{1} → r_{1} and R_{2} = l_{2} → r_{2} be two different program rules and t be a term which has no variables in common with R_{1} and R_{2}. If σ(l_{1}) = t, i.e., t is narrowable by rule R_{1} without instantiating any goal variable, then rule R_{2} need not be considered, because either R_{2} is not applicable or the result of applying R_{2} yields an instance of the application of R_{1}.

This means that lazy narrowing is complete in the sense of [37] even if the lazy narrowing derivation starting with an application of rule R_{2} to t is ignored. Hence we could try to match the left-hand side of some rule with the current goal before applying a narrowing step. If this is possible, we can perform the corresponding rewrite step and, by the previous lemma, ignore all other rules, i.e., we perform a deterministic computation step. Although this solves the problems exemplified in Example 4.2, it is not sufficient to exploit many possible deterministic computations. In general, rewrite steps must also be performed at inner positions in order to enable rewrite steps at outer positions. For instance, consider the rules of Examples 1.1 and 1.2 and the goal equation (0+0)∗z ≈ 0. A rewrite step by applying rules R_{3} or R_{4} to the left-hand side of the equation is not possible. Hence we try to perform a narrowing step, i.e., generate a choice point for the rules R_{3} or R_{4}, and so on. However, if we apply a rewrite step to the subterm (0+0) before the narrowing attempt, the equation is simplified to 0 ∗ z ≈ 0 using rule R_{1}, and we could further simplify the equation to the trivial one 0 ≈ 0 using rule R_{3}. Therefore, we could solve the equation without any nondeterministic narrowing step. The following lemma shows that deterministic rewrite steps at inner positions does not influence the applicability of narrowing steps at outer positions.

16Note that we consider a sequential implementation where the rules are applied in the given textual order.

Lemma 4.4 Let t, t′ be terms such that t →_{R} t′ is a rewrite step at position p. Then all narrowing rules which are applicable to t at a position p′, where p′ ≠ p is a position not below p, are also applicable to t′ with the same substitution of variables occurring in t.

Proof: This lemma is a consequence of the requirement for constructor-based rules: the subterm t|_{p} must have a defined function symbol at the top since t →_{R} t′ is a rewrite step at position p. If a narrowing rule is applicable to t at position p′, i.e., there is a rule l → r and a mgu σ of t|_{p′} and l, and p′ is a position above p (the case of independent positions is trivial since variables in t are not instantiated by the rewrite step), then there must be a variable position p′′ in l (i.e., l|_{p′′} ∈ X) such that σ(l)|_{p′′} contains the subterm t|_{p} (since all proper subterms of l contain only constructors and variables). But then there is also a unifier σ′ of t′|_{p′} and l which can be obtained by modifying σ for the variable l|_{p′′} (note that l has no multiple occurrences of variables, hence σ′_{|Var(t)} = σ_{|Var(t)}). Hence we can apply rule l → r to t′ at position p′.

The following theorem justifies deterministic rewrite steps at arbitrary lazy narrowing positions (see [37] for a detailed definition of lazy narrowing positions).

Theorem 4.5 Let t, t′ be terms such that t →_{R} t′ is a rewrite step at lazy narrowing position p. Then lazy narrowing is complete even if we ignore all alternative narrowing rules applicable to t.

Proof: Let t ⇝_{[p′,R,σ]} t′′ be an alternative lazy narrowing step. We show that we do not loose any solutions by ignoring this step and continuing with t′ instead of t′′.

p′ = p: By Lemma 4.3 applied to position p, t′′ is an instance of t′. Hence all solutions computed by narrowing derivations starting from t′′ are also computed by narrowing derivations starting from t′.

p′ is a position below p: Since p′ is a lazy narrowing position, the narrowing step at p′ is demanded by some rule which may be applicable at position p at some later point. However, similarly to the previous case, this alternative step at position p can be ignored without destroying completeness. Consequently, this narrowing step at position p′ can also be ignored. p′ is a position not below p and p′ ≠ p: By Lemma 4.4, this alternative narrowing step is also ap-

plicable to t′ with the same substitution of variables occurring in t. Hence we can ignore this step without destroying completeness.

As a consequence of this theorem, we can deterministically apply rewrite rules at any lazy narrowing position before a narrowing step. A simple induction shows that we can also deterministically apply a finite sequence of rewrite steps at lazy narrowing positions. I.e., we can combine lazy narrowing with lazy simplification (where lazy simplification positions are defined similarly to lazy narrowing positions [37]) without destroying completeness. However, this is only true for finite sequences of simplification steps (due to the proof by induction). Nevertheless, an infinite loop caused by simplification occurs in lazy narrowing derivations without simplification, too, since rewrite steps are also particular narrowing steps. The only difference is that the order of rule applications in simplification steps may be different from the order of rule applications in narrowing steps. Hence it may be the case that the simplification process runs into an infinite loop, whereas lazy narrowing without simplification first computes an answer and then runs into an infinite loop.

Example 4.6 Consider the rules of Example 1.2 and the following rule defining a nonterminating function:

inf → inf

If the goal equation x ∗ inf ≈ 0 should be solved, a lazy simplification strategy tries to evaluate the subterm inf to the constructor 0 in order to apply rule R_{4} to the left-hand side of the equation (i.e., the second argument of ∗ is a lazy narrowing position). Since the evaluation of inf loops, the simplification process does not terminate and no solution is computed. On the other hand, lazy narrowing without simplification narrows the left-hand side of the equation by applying rule R_{3}. This binds goal variable x to 0 and yields the trivial equation 0 ≈ 0. However, after the computation of this solution an attempt to apply the alternative rule R_{4} to the left-hand side is made which yields the same infinite loop as in the simplification process. □

Note that this different behavior is due to a particular sequential implementation of the strategy. In an implementation which collects all answers until the entire search space has been examined, we obtain no answer in both cases due to the infinite search space.

In order to ensure the termination of the simplification process even if we blindly apply all possible lazy simplification steps, we include only a terminating subset of the program rules for simplification. Since lazy narrowing is already complete without simplification, it is not necessary to perform rewrite steps with all possible program rules, but we can arbitrarily restrict the set of rules used for rewrite steps. In the light of the previous example, it is a reasonable decision to include a rule set with a terminating rewrite relation for simplification. This ensures the termination of the simplification process. The selection of this subset of rewrite rules could be done by the programmer or by the system (e.g., include only those rewrite rules for which a termination proof can be constructed). We have made the experience that, for most practical examples, termination proofs can be automatically constructed using syntactic termination orderings from term rewriting [7]. This is the case for all rules presented so far (of course, except for the first-rule of Example 4.1 and the inf-rule of Example 4.6). An example where a terminating subset of all program rules is used for simplification will be given in Section 5.3.

5 Application to Functional Logic Programs

In this section we discuss the usefulness of integrating simplification into lazy narrowing derivations with respect to different classes of functional logic programs. In general, we consider constructorbased confluent rewrite systems. However, there are various subclasses of such rewrite systems with different implications on the usefulness of integrating simplification. We will discuss the following three subclasses in more detail: inductively sequential systems [1] where the rules for each function can be organized in a hierarchical structure, orthogonal systems satisfying the strong nonambiguity condition (no overlapping in the left-hand sides of the rules), and weakly orthogonal systems with overlapping left-hand sides.

5.1 Inductively Sequential Programs

In many functional as well as functional logic programs, functions are defined by a case distinction on the different constructors occurring in the data type of the arguments. For instance, the definition of the addition function on natural numbers (cf. Example 1.1) is based on a case distinction for the first argument with respect to the constructors 0 and s. As another example consider the following rules defining a less-or-equal function on naturals:

\begin{matrix}0 ≤ & x  → & true & (R_{1}) \\ s(x) ≤ & 0  → & false & (R_{2}) \\ s(x) ≤ & s(y) → & x ≤ y & (R_{3}) \end{matrix}

Here is the main case distinction on the constructors of the first argument: if this argument is 0, then only rule R_{1} is applicable. If this argument has the constructor s at the top, then a further case distinction on the second argument is necessary to distinguish between rules R_{2} and R_{3}. Altogether, the rules can be organized in a hierarchical structure representing the various case distinctions. Such hierarchical structures have been introduced by Antoy [1] under the name definitional trees. A program for which the rules of each function symbol can be organized in a definitional tree is called inductively sequential. Antoy, Echahed and Hanus [2] have defined for inductively sequential programs a narrowing strategy, called needed narrowing, which is optimal in the following sense: (1) it reduces only needed subterms in a narrowing step, i.e., subterms which must be reduced in any possible successful narrowing derivation, (2) it computes the shortest narrowing derivations if common subterms are shared, and (3) the solutions computed by two different narrowing derivations are independent. The needed narrowing steps are computed using the structure of definitional trees. Thus it can be efficiently implemented by pattern matching, and the strategy has an outermost (lazy) behavior.

Due to the optimality of needed narrowing the natural question arises whether the inclusion of simplification has an effect for this class of programs. To answer this question, we recall the applicability conditions for a rewrite step. A functional expression can be reduced by a rewrite step if the arguments of the function call are sufficiently instantiated such that the left-hand side of some rule can be matched with the current call. Since the program is inductively sequential, there is always at most one rule matching the current call and this rule will be selected in the next narrowing step without instantiating any goal variables (see [2] for a detailed description of the strategy). Therefore, a possible lazy reduction step is also computed by the needed narrowing strategy as a narrowing step, i.e., the inclusion of simplification steps has no effect. This is formally justified by the following proposition.

Proposition 5.1 Let R be a set of inductively sequential rules. Then the integration of simplification does not shorten any needed narrowing derivation.

Proof: By definition, rewrite steps are also particular narrowing steps. Thus any narrowing derivation with intermediate simplification steps is also a pure narrowing derivation. Since needed narrowing computes the shortest narrowing derivations [2], simplification cannot shorten any needed narrowing derivation.

Hence it is unnecessary to integrate simplification with program rules in narrowing derivations for the class of inductively sequential programs. Therefore, narrowing derivations can be optimized for such programs only if inductive consequences are added as simplification rules. Actually, Example 3.16 is an inductively sequential program and we have shown that simplification with the additional inductive consequence x ∗ 0 → 0 can reduce the search space.

5.2 Orthogonal Programs

The main example where we have demonstrated the improvements of simplification with respect to lazy narrowing (Example 1.2) has the property that two rules have overlapping left-hand sides. In the following we will show that the inclusion of simplification is useful even if there are no overlapping rules.

Example 5.2 Consider the following rewrite rules:

\begin{aligned}f(0, s(x), y) & → & 0 & (R_{1}) \\ f(s(x), y, 0) & → & 0 & (R_{2}) \\ f(y, 0, s(x)) & → & 0 & (R_{3}) \end{aligned}  \begin{aligned}one(0) & → & s(0) & (R_{4}) \\ one(s(x)) & → & one(x) & (R_{5}) \end{aligned}

This is an orthogonal term rewriting system since all rules are left-linear and do not overlap in the left-hand sides. However, it is not inductively sequential since there is no argument which represents a case distinction on the constructors 0 and s. In fact, simplification has an effect if we consider the goal equation f(one(z), 0, s(0)) ≈ 0. Naive lazy narrowing first tries to apply rule R_{1} to the left-hand side of this equation. Since the first argument of the rule’s left-hand side is 0, the evaluation of the actual argument one(z) is required in order to decide the unifiability of the first argument.^{17} Similarly to Example 1.2, the evaluation of one(z) has an infinite search space and a sequential implementation does not compute any result since all evaluations of one(z) yields s(0) as the result which is not unifiable with the demanded value 0. However, if we simplify the goal equation before the attempt to apply a narrowing step, we use rule R_{3} for a rewrite step which yields the trivial equation 0 ≈ 0. Hence the infinite search space is avoided. □

17We assume that arguments are unified from left to right, otherwise a similar example can be constructed.

5.3 Weakly Orthogonal Programs

In Sections 5.1 and 5.2 we have shown that the boundary of the usefulness of simplification in lazy narrowing derivations is between inductively sequential and orthogonal systems. If we do not include inductive consequences for simplification, we conjecture that, for practical applications, the most interesting class, where simplification is useful, is the class of weakly orthogonal programs which have rules with overlapping left-hand sides. Example 1.2 contains such a simple program, but the recursively defined constant function one may not convince the reader. Therefore, we will demonstrate the positive effects of simplification by a more natural example.

Example 5.3 Consider the following rules defining the Boolean operator ∨ and the predicate even on natural numbers:

\begin{matrix}true ∨ b → & true & (R_{1}) & even(0) → & true & (R_{4}) \\ b ∨ true → & true & (R_{2}) & even(s(0)) → & false & (R_{5}) \\ false ∨ false → & false & (R_{3}) & even(s(s(x))) → & even(x) & (R_{6}) \end{matrix}

This rewrite system is weakly orthogonal since rules R_{1} and R_{2} overlap. Now consider the goal equation even(z) ∨ true ≈ true (note that this goal equation could also be the result of the more general equation even(z) ∨ b ≈ true where the Boolean variable b has been bound to true in the preceding computation). Naive lazy narrowing without simplification tries to apply a narrowing step with rule R_{1}. Since the value of the first ∨-argument is demanded by this rule, the subterm even(z) is evaluated to a constructor-headed term by narrowing. There are infinitely many possibilities to do this, in particular, the constructor true is derived by instantiating variable z with the values s^{2∗i}(0), i ≥ 0. Therefore, lazy narrowing without simplification has an infinite search space and computes the additional specialized solutions {z ↦ s^{2∗i}(0)}. Moreover, in a sequential implementation of lazy narrowing by backtracking [18], only the infinite set of specialized solutions would be computed without ever trying the second ∨-rule. On the other hand, if the equation is first simplified by applying rule R_{2} to the left-hand side, we immediately obtain the trivial equation true ≈ true and avoid the infinite search space. □

We have mentioned that our method is complete even in the presence of nonterminating functions if a terminating subset of the program rules is used for simplification. This is demonstrated by a modification of the previous example.

Example 5.4 Consider the rules for ∨ of Example 5.3 (R_{1}, R_{2}, R_{3}) and the following new rules for not, even and odd:

\begin{matrix}not(true) → & false & (R_{4}) & even(x) → & not(odd(x)) & (R_{6}) \\ not(false) → & true & (R_{5}) & odd(x) → & not(even(x)) & (R_{7}) \end{matrix}

Although even and odd are nonterminating functions, it is an admissible program. We use the terminating subset of the rules {R_{1}, R_{2}, R_{3}, R_{4}, R_{5}} for simplification.^{18} Consider the goal equation even(z) ∨ not(false) ≈ true. Lazy narrowing without simplification tries to compute the head normal form of the subterm even(z) since its value is demanded by rule R_{1}. Since this computation is nonterminating, naive lazy narrowing has an infinite search space. The same holds for lazy narrowing with the dynamic cut operator [32]. However, lazy narrowing with simplification tries to apply rewrite steps first. No simplification rule is applicable to the entire left-hand side of the goal equation since the arguments are not in head normal form. Due to the lazy simplification strategy, we try to evaluate the arguments by simplification steps. The subterm even(z) cannot be further simplified since rule R_{6} is not included in the set of simplification rules. The second argument not(false) can be simplified to true by R_{5} which causes the simplification of the complete left-hand side to true by R_{2}. Hence we obtain the trivial equation true ≈ true and the infinite search space is avoided. □

18Note that the termination property of this subset can be automatically checked.

5.4 A Benchmark

In order to test our new execution strategy on larger programs, we have implemented an interpreter for lazy narrowing with simplification in Prolog [23]. An interesting class of programs, where simplification has a relevant effect on the search space, are “generate-and-test” programs. A typical example for such programs is the “permutation sort” program, where a list is sorted by enumerating all permutations and checking whether they are sorted. In the Prolog version of this program ([44], p. 55), all permutations are enumerated and checked. However, if we execute the same program by lazy narrowing with simplification (in this case predicates are considered as Boolean functions, see [14], p. 182), then the simplification process cuts some parts of the search space so that not all permutations are completely enumerated. Therefore, we obtain the following execution times in seconds (Sicstus-Prolog 2.1 on a Sparc10) to sort the list [n,...,2,1] for different values of n:

Length n Prolog Lazy Lazy+Simp
4  0.01  0.02  0.04
5  0.01  0.1  0.1
6  0.05  0.8  0.2
7  0.3  5.4  0.5
8  2.6  45.9  1.1
9  23.6 420.1  2.5
10  240.9 4389.2  5.5

The column “Lazy+Simp” contains the execution times for lazy narrowing with simplification, the column “Lazy” the times for pure lazy narrowing without simplification, and the column “Prolog” the times for the direct implementation of permutation sort in Prolog. The search spaces of “Prolog” and “Lazy” are essentially the same. The slow timings of “Lazy” is due to the overhead of the lazy narrowing interpreter (which is also written in Prolog). However, the last column shows that this overhead can be compensated by the search space reduction due to the simplification process.

6 Conclusions and Related Work

In this paper we have shown how to improve the execution mechanism of functional logic languages, where we have considered the most important classes of programs: ground confluent and terminating rewrite systems, and weakly orthogonal and possibly nonterminating rewrite systems. The basic idea of our improvement is the integration of a deterministic simplification process into lazy narrowing derivations. This can be done in a simple way by using the program rules (or a terminating subset of the program rules in the presence of nonterminating rules) as simplification rules. The simplification strategy must be identical to the narrowing strategy in order to avoid additional computation steps caused by the simplification process. For particular and practically relevant classes of functional logic programs (orthogonal and weakly orthogonal programs) this has the positive effect that the search space is reduced without destroying completeness. Although we have emphasized the effect of simplification to the search space, the inclusion of simplification can also have an effect on the run time even if the search space is not reduced. For instance, if all program rules are used for simplification, ground goals are evaluated by simplification without generating any choice point, whereas a lazy narrowing implementation would generate (and afterwards delete) choice points. Hence lazy narrowing with simplification combines the features from functional and logic programming also from an implementation point of view.

We have mentioned in the introduction and in Section 2 that the idea of exploiting deterministic computations by including simplification in functional logic languages has been proposed mainly for eager narrowing strategies like basic [38, 42], innermost [14] or innermost basic narrowing [25]. Echahed [12] has shown how to integrate normalization (with inductive consequences) in any narrowing strategy, but he requires strong restrictions on the set of rules (termination and uniformity, which is stronger than inductive sequentiality). As far as we know, the present paper is the first attempt to include simplification into narrowing derivations even in the presence of nonterminating functions.^{19} The only related work for this class of programs is the paper of Loogen and Winkler [32] which proposes the dynamic cut to detect deterministic narrowing steps after the unification phase. As discussed in Section 4, this does not avoid the generation of choice points, and the cut of infinite derivation paths depends on the order of rules. The basic difference of our method is that we check the applicability of a deterministic computation step before we apply a nondeterministic step. Hence we prefer deterministic computations to nondeterministic computations. This qualifies our execution method as the operational principle of efficient functional logic languages.

Loogen et al. [31] have proposed to improve lazy narrowing strategies by reordering the unification steps in rule applications. For this purpose they use a version of definitional trees [1] extended to weakly orthogonal rewrite systems. In order to handle overlapping left-hand sides, they introduce nondeterministic choice nodes in definitional trees. However, these choice nodes have the effect that possible deterministic computations are not detected. For instance, the infinite search spaces of naive lazy narrowing in Examples 1.2, 5.2 and 5.3 would also occur with respect to their improved strategy.

Another alternative to improve lazy narrowing has been proposed by Moreno-Navarro et al. [36]. They use information about demanded arguments to avoid reevaluations of expressions during unification with different rules. Since they do not change the order of argument evaluations and rules, the infinite search spaces avoided by simplification still occur in their approach.

The integration of simplification into lazy narrowing derivations requires new implementation techniques for functional logic languages. Current efficient implementations of lazy narrowing are mainly based on extensions of reduction machines used for the implementation of functional languages [5, 18, 30, 35]. The inclusion of simplification requires the implementation of an intermediate reduction process. This could be done by techniques proposed for the efficient implementation of normalizing narrowing [19, 20] or by the implementation of demons waiting for the sufficient instantiation of function arguments [27].

19The combination of lazy narrowing with deterministic reduction steps has been also considered by Josephson and Dershowitz [27]. However, they provide no completeness proof but refer to [10] where only the completeness of naive narrowing without simplification and without a particular lazy strategy is proved for terminating conditional rules.

Acknowledgements. The author is grateful to the anonymous referees for their suggestions to improve the paper. The research described in this paper was mainly made during the author’s stay at the Max-Planck-Institut für Informatik in Saarbrücken, Germany. It was supported in part by the German Ministry for Research and Technology (BMFT) under grant ITS 9103 and by the ESPRIT Basic Research Working Group 6028 (Construction of Computational Logics). The responsibility for the contents of this publication lies with the author.

References

[1] S. Antoy. Definitional Trees. In Proc. of the 3rd International Conference on Algebraic and Logic Programming, pp. 143–157. Springer LNCS 632, 1992.

[2] S. Antoy, R. Echahed, and M. Hanus. A Needed Narrowing Strategy. In Proc. 21st ACM Symposium on Principles of Programming Languages, pp. 268–279, Portland, 1994.

[3] F. Baader and J.H. Siekmann. Unification Theory. In D.M. Gabbay, C.J. Hogger, and J.A. Robinson, editors, Handbook of Logic in Artificial Intelligence and Logic Programming, pp. 41–125. Oxford University Press, 1994.

[4] D. Bert and R. Echahed. Design and Implementation of a Generic, Logic and Functional Programming Language. In Proc. European Symposium on Programming, pp. 119–132. Springer LNCS 213, 1986.

[5] M.M.T. Chakravarty and H.C.R. Lock. The Implementation of Lazy Narrowing. In Proc. of the 3rd Int. Symposium on Programming Language Implementation and Logic Programming, pp. 123–134. Springer LNCS 528, 1991.

[6] J. Darlington and Y. Guo. Narrowing and unification in functional programming - an evaluation mechanism for absolute set abstraction. In Proc. of the Conference on Rewriting Techniques and Applications, pp. 92–108. Springer LNCS 355, 1989.

[7] N. Dershowitz. Termination of Rewriting. J. Symbolic Computation, Vol. 3, pp. 69–116, 1987.

[8] N. Dershowitz and J.-P. Jouannaud. Rewrite Systems. In J. van Leeuwen, editor, Handbook of Theoretical Computer Science, Vol. B, pp. 243–320. Elsevier, 1990.

[9] N. Dershowitz, S. Mitra, and G. Sivakumar. Equation Solving in Conditional AC-Theories. In Proc. of the 2nd International Conference on Algebraic and Logic Programming, pp. 283–297. Springer LNCS 463, 1990.

[10] N. Dershowitz and D.A. Plaisted. Equational Programming. In J.E. Hayes, D. Michie, and J. Richards, editors, Machine Intelligence 11, pp. 21–56. Oxford Press, 1988.

[11] R. Echahed. On Completeness of Narrowing Strategies. In Proc. CAAP’88, pp. 89–101. Springer LNCS 299, 1988.

[12] R. Echahed. Uniform Narrowing Strategies. In Proc. of the 3rd International Conference on Algebraic and Logic Programming, pp. 259–275. Springer LNCS 632, 1992.

[13] M.J. Fay. First-Order Unification in an Equational Theory. In Proc. 4th Workshop on Automated Deduction, pp. 161–167, Austin (Texas), 1979. Academic Press.

[14] L. Fribourg. SLOG: A Logic Programming Language Interpreter Based on Clausal Superposition and Rewriting. In Proc. IEEE Internat. Symposium on Logic Programming, pp. 172–184, Boston, 1985.

[15] J.H. Gallier and W. Snyder. Complete Sets of Transformations for General E-Unification. Theoretical Computer Science, Vol. 67, pp. 203–260, 1989.

[16] A. Geser and H. Hussmann. Experiences with the RAP system – a specification interpreter combining term rewriting and resolution. In Proc. of ESOP 86, pp. 339–350. Springer LNCS 213, 1986.

[17] E. Giovannetti, G. Levi, C. Moiso, and C. Palamidessi. Kernel LEAF: A Logic plus Functional Language. Journal of Computer and System Sciences, Vol. 42, No. 2, pp. 139–185, 1991.

[18] W. Hans, R. Loogen, and S. Winkler. On the Interaction of Lazy Evaluation and Backtracking. In Proc. of the 4th International Symposium on Programming Language Implementation and Logic Programming, pp. 355–369. Springer LNCS 631, 1992.

[19] M. Hanus. Compiling Logic Programs with Equality. In Proc. of the 2nd Int. Workshop on Programming Language Implementation and Logic Programming, pp. 387–401. Springer LNCS 456, 1990.

[20] M. Hanus. Efficient Implementation of Narrowing and Rewriting. In Proc. Int. Workshop on Processing Declarative Knowledge, pp. 344–365. Springer LNAI 567, 1991.

[21] M. Hanus. Improving Control of Logic Programs by Using Functional Logic Languages. In Proc. of the 4th International Symposium on Programming Language Implementation and Logic Programming, pp. 1–23. Springer LNCS 631, 1992.

[22] M. Hanus. The Integration of Functions into Logic Programming: From Theory to Practice. Journal of Logic Programming, Vol. 19&20, pp. 583–628, 1994.

[23] M. Hanus. Efficient Translation of Lazy Functional Logic Programs into Prolog. In Proc. Fifth International Workshop on Logic Program Synthesis and Transformation, pp. 252–266. Springer LNCS 1048, 1995.

[24] M. Hanus. On Extra Variables in (Equational) Logic Programming. In Proc. International Conference on Logic Programming, pp. 665–679. MIT Press, 1995.

[25] S. Hölldobler. Foundations of Equational Logic Programming. Springer LNCS 353, 1989.

[26] J.-M. Hullot. Canonical Forms and Unification. In Proc. 5th Conference on Automated Deduction, pp. 318–334. Springer LNCS 87, 1980.

[27] A. Josephson and N. Dershowitz. An Implementation of Narrowing. Journal of Logic Programming (6), pp. 57–77, 1989.

[28] J.-P. Jouannaud and H. Kirchner. Completion of a set of rules modulo a set of equations. SIAM Journal on Computing, Vol. 15, No. 4, pp. 1155–1194, 1986.

[29] S. Krischer and A. Bockmayr. Detecting Redundant Narrowing Derivations by the LSE-SL Reducibility Test. In Proc. RTA’91. Springer LNCS 488, 1991.

[30] R. Loogen. Relating the Implementation Techniques of Functional and Functional Logic Languages. New Generation Computing, Vol. 11, pp. 179–215, 1993.

[31] R. Loogen, F. Lopez Fraguas, and M. Rodríguez Artalejo. A Demand Driven Computation Strategy for Lazy Narrowing. In Proc. of the 5th International Symposium on Programming Language Implementation and Logic Programming, pp. 184–200. Springer LNCS 714, 1993.

[32] R. Loogen and S. Winkler. Dynamic Detection of Determinism in Functional Logic Languages. In Proc. of the 3rd Int. Symposium on Programming Language Implementation and Logic Programming, pp. 335–346. Springer LNCS 528, 1991. Extended version to appear in Theoretical Computer Science, 1995.

[33] A. Martelli and U. Montanari. An Efficient Unification Algorithm. ACM Transactions on Programming Languages and Systems, Vol. 4, No. 2, pp. 258–282, 1982.

[34] A. Martelli, G.F. Rossi, and C. Moiso. Lazy Unification Algorithms for Canonical Rewrite Systems. In Hassan Aït-Kaci and Maurice Nivat, editors, Resolution of Equations in Algebraic Structures, Volume 2, Rewriting Techniques, chapter 8, pp. 245–274. Academic Press, New York, 1989.

[35] J.J. Moreno-Navarro, H. Kuchen, R. Loogen, and M. Rodríguez-Artalejo. Lazy Narrowing in a Graph Machine. In Proc. Second International Conference on Algebraic and Logic Programming, pp. 298–317. Springer LNCS 463, 1990.

[36] J.J. Moreno-Navarro, H. Kuchen, J. Marino-Carballo, S. Winkler, and W. Hans. Efficient Lazy Narrowing Using Demandedness Analysis. In Proc. of the 5th International Symposium on Programming Language Implementation and Logic Programming, pp. 167–183. Springer LNCS 714, 1993.

[37] J.J. Moreno-Navarro and M. Rodríguez-Artalejo. Logic Programming with Functions and Predicates: The Language BABEL. Journal of Logic Programming, Vol. 12, pp. 191–223, 1992.

[38] W. Nutt, P. Réty, and G. Smolka. Basic Narrowing Revisited. Journal of Symbolic Computation, Vol. 7, pp. 295–317, 1989.

[39] P. Padawitz. Computing in Horn Clause Theories, volume 16 of EATCS Monographs on Theoretical Computer Science. Springer, 1988.

[40] C. Prehofer. Higher-Order Narrowing. In Proc. Ninth Annual IEEE Symposium on Logic in Computer Science, pp. 507–516, 1994.

[41] U.S. Reddy. Narrowing as the Operational Semantics of Functional Languages. In Proc. IEEE Internat. Symposium on Logic Programming, pp. 138–151, Boston, 1985.

[42] P. Réty. Improving basic narrowing techniques. In Proc. of the Conference on Rewriting Techniques and Applications, pp. 228–241. Springer LNCS 256, 1987.

[43] J.R. Slagle. Automated Theorem-Proving for Theories with Simplifiers, Commutativity, and Associativity. Journal of the ACM, Vol. 21, No. 4, pp. 622–642, 1974.

[44] L. Sterling and E. Shapiro. The Art of Prolog. MIT Press, 1986.