Mechanizing Induction∗ Deepak Kapur Computer Science Department State University of New York Albany, NY 12222 [email protected]

Abstract Inductive reasoning is employed in many application domains while reasoning about properties of computations, particularly in designing specifications and (software and hardware) descriptions implementing specifications as well as data base integrity constraints. An approach based on cover sets for mechanizing inductive reasoning is discussed. This approach has been implemented in a theorem prover RRL (Rewrite Rule Laboratory) and a proof management system TECTON. It has been used to prove many nontrivial theorems about numbers, lists and sequences, as well as reason about sequential and parallel programs, and hardware descriptions. The cover set method is based on the assumption that a function symbol is defined using a finite set of terminating (conditional or unconditional) rewrite rules. The left sides of the rules are then used to design different cases of an induction scheme, and recursive calls to the function made in the right side can be used to design appropriate instantiations for generating induction hypotheses. A number of powerful heuristics have been incorporated into the implementation of the cover set method with an emphasis to do proofs with minimal human guidance and intervention. Examples from different application domains - reasoning about specifications of parallel algorithms and hardware descriptions, and sorting algorithms will be used to illustrate various aspects of the approach.

Key Words: Mechanizing Induction, Automated Theorem Proving, Cover Set, Heuristics, Presburger Arithmetic, Generalization, Lemma Generation, Semantic Unification.



Partially supported by the National Science Foundation Grant nos. CCR-9303394 and CCR-9308016.

1

1

Introduction

While reasoning about computations, it is often necessary to do proofs by induction on finitely generated data structures and/or on the steps of a computation. A proof of any nontrivial property about a computation requires inductive reasoning. In order to provide effective tools to aid a user in designing algorithms, specifications and hardware descriptions, it thus becomes necessary to develop methods for mechanizing proofs by induction. In these notes, an approach based on cover set method first outlined in my former student Hantao Zhang’s Ph.D. thesis is discussed [14, 15]. This approach is influenced by Boyer and Moore’s seminal work on mechanizing proofs by induction of Lisp definitions in their constructive logic [2, 3]. While mechanizing proofs by induction, a crucial problem that often needs to be addressed is to decide on an induction scheme that leads to an appropriate induction hypothesis (or a set of induction hypotheses) to carry out the proof. This is related to an appropriate choice of a variable (or a finite set of variables) in a conjecture to perform induction on. Boyer and Moore proposed designing induction schemes based on terminating function definitions. Typically the definitions of function symbols appearing in a conjecture are considered as candidates for designing induction schemes. The soundness of such an induction scheme is based on a well-founded ordering used to show the termination of the function definition. This insight often results in generation of appropriate induction hypotheses which in many cases, can be used to prove (or disprove) a conjecture. The cover set approach is similar in spirit. Unlike Boyer and Moore’s system in which definitions are given as Lisp functions, function definitions and their properties are specified as equations (or conditional equations). Equations constituting function definitions are oriented into terminating rewrite rules using a well-founded ordering. The left sides of the rewrite rules are then used to design different cases of an induction scheme, and recursive calls to the function made in the right side can be used to design appropriate instantiations for generating induction hypotheses. Since the rewrite rules are terminating, the soundness of this approach is justified. Rewrite rules in a function definition could be given in terms of constructors or nonconstructors or both. Because of that, an induction scheme generated by the cover set method is a generalization of the principle of mathematical induction for natural numbers and the principle of structural induction obtained from the constructors of a data structure. The cover set approach has been implemented in the theorem prover Rewrite Rule Laboratory (RRL) [12] since 1987 and a proof management system Tecton built on top of RRL [5], and it has been used to prove many nontrivial theorems and reason about sequential as well as parallel programs.

1.1

An informal overview using an example

First we provide an informal review of the cover set approach using a simple example. Consider the following definition of the divisibility predicate on natural numbers; the functions 0, s, 0. This formula simplifies to true using the (standard recursive) definition of + (in terms of 0 and s) and the first rule. The second base case is divides(u, v + v) if divides(u, v) ∧ (u > 0) ∧ (v < u) ∧ v "= 0, which trivially simplifies to true since divides(u, v) in the condition simplifies to f alse under the condition v < u and v "= 0 using the second rule. The induction step is:

divides(u, (u + v) + (u + v)) if divides(u, u + v) ∧ u > 0 ∧ (v < u + v), with the induction hypothesis being: divides(u, v + v) if divides(u, v) ∧ u > 0. Using the properties of 0, which is the induction hypothesis. So the conjecture is proved. The reader would have noticed how using the well-founded ordering suggested by the definition of divides leads to an induction hypothesis which turned out to be useful in proving this conjecture in which divides appears. Also observe a close connection between the rewrite rules defining divides and the induction scheme generated for x, y, the arguments to divides in the conjecture. Below, we formalize these ideas.

2

Cover Sets and Induction Schemes

Let F be a set of function symbols with a given signature, i.e., for each f in F , its arity is specified as well as the type of each argument and type of the result returned is specified. Let T (F, X) denotes the set of type-correct terms constructed using function symbols in F and variables in a set X. Given a term t, let V ars(t) stand for the set of variables that occur in t. A term t whose outermost function symbol is f is called an f -term. An f -term of the form f (x1 , · · · , xn ) where xi ’s are distinct variables, is called a basic f -term (or simply a basic term). A substitution σ is a finite map from variables to terms (of appropriate types) written as {x1 → s1 , · · · , xk → sk } , xi ∈ X and si ∈ T (F, X), 1 ≤ i ≤ k. The substitution σ ◦ τ denotes the composition of substitutions σ and τ : σ ◦ τ (x) = σ(τ (x)). Given a substitution σ, Eσ denotes σ viewed as equations: σ = {x1 → s1 , · · · , xk → sk }, Eσ = {x1 = s1 , · · · , xk = sk }. The symbol =E is used to denote equality on terms with respect to a set of (possibly conditional) equations E.

A definition of a function symbol f ∈ F is a finite set D of conditional equations of the form li = ri if condi , 1 ≤ i ≤ m, where condi is optional; li is an f -term from T (F, X), ri is a term in T (F, X)

of the same type as of l, and condi is a boolean term and is a conjunction of literals built out of terms in T (F, X) such that V ars(ri ) ⊆ V ars(li ) and V ars(condi ) ⊆ V ars(li ). Further, it is assumed that each conditional equation can be oriented into a terminating rewrite rule, i.e., there exists a well-founded reduction ordering ) over T (F, X) which is preserved under substitutions such that li ) ri and li ) condi [4]. For each type, we associate a finite set of constructors used to generate the values of the type. Constructors are a subset of F , and there are no definitions for constructors. Constructors may or may not be free. For natural numbers, the constructors are 0 and s (successor), which are free; that means that (i) the term 0 is assumed to stand for a number different from a number represented by s(x), and (ii) if two terms s(x) and s(y) stand for the same number, then the arguments x and y also stand for the same number. For integers, the constructors 0, s, and p (predecessor) are not free since 0 = s(p(0)) = p(s(0)). If constructors are not free, then relations over constructor symbols are assumed to be expressed as a finite set of equations. Function definitions may be given using nonconstructors as arguments. The definition of divides, for example, is given in terms of +, 0, < instead of 0, s. The definition of a function symbol f in which the arguments to f in the rewrite rules are constructor terms (i.e., built using constructor symbols), is called constructor-based. The definition of divides is not constructor-based, whereas the definitions of +, even, append, same and rev given later in the paper are constructor-based. Let E be a finite set of equations possibly relating constructors as well as including definitions of nonconstructors used in defining other nonconstructors.

2.1

Cover sets

The cover set approach uses function definitions for generating the subgoals to be considered as well as for induction hypotheses. Induction is performed using a well-founded rewrite relation induced by the rewrite rules in a function definition. The left sides of rewrite rules in a definition D of f are used to generate different subgoals of an inductive proof. Each rewrite rule covers a subset of the domain of f . For example, the first rule defining divides covers the case when the first argument is a number but the second argument is 0. The second rule covers the case when the second argument is nonzero and smaller than the first argument. Left sides of rules defining f can be used to generate instantiation for variables in a conjecture. For generating induction hypotheses, any (and all) smaller instantiation(s) in the rewrite relation can be used. One convenient way to generate smaller instantiations for induction hypothesis(es) is to use recursive calls in the right side of terminating rewrite rules. If the rewrite rules completely define f , then all possible values for the arguments to f are covered thus leading to an induction scheme. Otherwise an induction scheme is generated only for a subset of the domain covered by the rewrite rules defining f . Such an induction scheme can still be used for proofs by induction with some care. For each rewrite rule, a formula can be constructed expressing the subset of the domain of f covered by the rewrite rule. The subset of domain covered by the definition D of f is then simply the disjunction of the formulas corresponding to each rewrite rule. Let x1 , · · · , xn be new variables to stand for the arguments of f . Corresponding to the left side, say l = f (t1 , · · · , tn ) of each rule l → r if cond in the definition D of f , we have a conjunction x1 = t1 ∧· · ·∧xn = tn ∧cond expressing the range of arguments covered by the rule. Variables xi ’s are dependent since their values are determined by other variables,

which are independent. The above can also be viewed as: ∃u1 , · · · , ui , · · · (x1 = t1 ∧ · · · ∧ xn = tn ∧ cond), where ui ’s are all the variables appearing in tj ’s. The above formula has xi ’s as free variable and is true for those values of xi ’s for which it is possible to find instantiations of uj ’s such that xi = ti , 1 ≤ i ≤ n and cond is satisfied. If ti ’s are nonconstructor terms, then E, which includes the definitions of these nonconstructors, must be used to relate values, i.e., = is to be interpreted as =E . Even if ti ’s are constructor terms, it is necessary to use =E if there are relations over constructors. Let Φ(x1 , · · · , xn )f , or simply Φf , stand for the disjunction of conjunctions corresponding to each rule in the definition D of f . The formula specifies the n-tuple of values covered by D. If the formula is valid, then D is complete. For divides, Φ is: ∃u(x1 = u ∧ x2 = 0) ∨ ∃u, v(x1 = u ∧ x2 = v ∧ v < u ∧ v "= 0) ∨ ∃u, v(x1 = u ∧ x2 = u + v ∧ v < u + v), which can be further simplified to: ∃u, v[(x1 = u ∧ x2 = 0) ∨ (x1 = u ∧ x2 = v ∧ v < u ∧ v "= 0) ∨ (x1 = u ∧ x2 = u + v ∧ v < u + v)]. Definition of a cover set A cover set C for a function symbol f with a definition D is a finite set of triples where each triple is derived from a rewrite rule in D. For a conditional rule l → r if cond, the first component of the triple is the tuple of arguments of f in l, the second component is a set consisting of all tuples serving as arguments to f in r and the third component is the set of all literals in cond. A triple could have its second and third components to be the empty set. A cover set Cf associated with a function symbol f is complete if and only if Φf is valid. This implies that for any n-tuple < e1 , · · · , en > of ground constructor terms over domains of f , there exists a cover set triple, ci = , {· · · , < s!1 , · · · , s!n >, · · ·}, cond > and a substitution σ such that σ(si ) =E ei , 1 ≤ i ≤ n, and σ(cond) =E true. The triple ci is said to cover the tuple < e1 , · · · , en >. The cover set based on the definition of divides is:

(C1 ) : {, {}, {} >, , {}, {v < u, v "= 0} >, , {< u, v >}, {v < u+v} >}. A cover set generated from a constructor-based definition contains terms only over constructors. Further if there are no relations on constructors, then in the definition of a complete cover set, =E is replaced by = and matching can be used.

2.2

Induction schemes

An induction scheme can be easily generated from a cover set Cf of f since it is similar to Cf . An induction scheme is a finite set of induction cases of the form , {· · · , < θi , condi , repli >, · · ·} >, where < σc , condc , replc > is used to generate the induction conclusion and each triple in {· · · , < θi , condi , repli >, · · ·} is used to generate an induction hypothesis. Each of these components of an induction case is obtained from a cover set triple , {· · · , < si1 , · · · , sin >, · · ·}, cond >

in a cover set Cf of f as follows: σc = {x1 → s1 , · · · , xn → sn }, condc = cond, and replc = {p ← f (s1 , · · · , sn )}, where p is the position of a basic f -term f (x1 , · · · , xn ) in C; similarly, θi = {x1 → si1 , · · · , xn → sin }, condi = cond, and repli = {p ← f (si1 , · · · , sin )}. A position is a sequence of nonnegative integers used to refer to a subterm in a term. An equation will be considered as a term with = as the binary predicate; a conditional equation will be considered as a term with = as the binary predicate whose second argument is an if term, where if is a considered as a binary function. In conjecture (P1 ), for instance, the position of divides(x, y) is 2.2.1 as the conjecture is viewed as an abbreviation for divides(x, y + y) = (true if divides(x, y) ∧ x > 0). The replacement component (the third component in the tuples) is, strictly speaking, unnecessary. It is included to avoid duplicate work especially in case when substitutions must be obtained with respect to =E . Until a later section on semantic based analysis, this component can be ignored. The substitution σc and each of the substitutions θi are linked through the variables shared among the left hand side and the recursive calls on the right hand side of the rule from which the cover set triple is derived. The variables whose substitutions are not invariant across the induction conclusion and the hypotheses are called induction variables. Let indvars(φ) denote the induction variables of φ and V ars(φ) denote all the variables substituted for in an induction scheme φ. For example, the induction scheme from the cover set of divides is: (I1 ) : {, {} >, v}, which simplify to {x → 2 + v, u → 2}.7 In a similar manner, the substitution corresponding to the induction hypothesis is obtained to be {x → v, u → 2}. Hence the induction scheme is given as: {--{x → 0}, {}, {1 ← divides(2, 0)}., {}., --{x → 1}, {}, {1 ← divides(2, 1)}., {}., --{x → 2 + v}, {}, {1 ← divides(2, 2 + v)}., {-{x → v}, {}, {1 ← divides(2, v)}.}.}. The induction scheme for the term divides(2, s(x)) at position 2.1 in the conjecture is computed as follows. No induction case is generated corresponding to the first cover set triple, since 0 and s(x) cannot be unified using LA. ¿From the second cover set triple, the constraints are: {u! = 2, v ! = s(x)} with context {v ! < u! , v ! "= 0}, which simplifies using LA to {x → 0, u! → 2, v ! → 1}. ¿From the third cover set triple, the constraints corresponding to the conclusion are: { u! = 2, u! + v ! = s(x)} with context {u! + v ! > v ! }, which simplifies to: {x → v ! + 1, u! → 2}. The constraints for the hypothesis are: {u! = 2, v ! = s(x)} with context {u! + v ! > v ! }, which simplifies to: {x → v ! − 1, u! → 2} along with the feasibility constraint {v ! ≥ 1}. For divides(2, s(x)), the induction scheme is specified as: {--{x → 0}, {}, {2.1 ← divides(2, s(0))}., {}., --{x → v ! + 1}, {}, {2.1 ← divides(2, 2 + v ! )}., {-{x → v ! − 1}, {v ! ≥ 1}, {2.1 ← divides(2, v ! )}.}.}.

7.1.1

6

Modified algorithm for generating an induction scheme

• Input : A conjecture C of the form l = r if cond, an LA-based definition D of an n-ary function f and a term t = f (t1 , · · · , tn ) at a position p in C.

This example is taken from the Nqthm Corpus. This conjecture is proved there with the help of an explicit induction hint. 7 Note that v ≥ 0 is an implicit feasibility constraint for any natural number v which is left unspecified.

• Output : An induction scheme based on D. • Method: 1. Initialize: Compute the LA-based cover set Cf using D.

2. Compute induction schemes: For each cover set triple, c = --s1 , · · · , sn ., {· · · , -s!1 , · · · , s!n ., · · ·}, cond. in Cf do:

(a) Generate induction conclusion: The induction conclusion of the form -σc , condc , replc . is generated as: i. Set up constraint equations CE = {ti = si | 1 ≤ i ≤ n}. ii. Solve CE using LA with context {cond}. If solvable, let σ = {xi → ui } be the substitution obtained which satisfies the occur-check, where ui are linear terms possibly involving new variables and xi ∈ V ars(t) ∪ V ars(c). Let cc be the set of feasibility constraints over V ars(c). No solution corresponds to a vacuous induction case. iii. Let µ be the restriction of σ on V ars(c). σc is the restriction of σ on V ars(t); condc is µ(cc ) ∪ µ(cond) 8 ; replc is {p ← f (σ(s1 ), · · · , σ(sk ))}. (b) Generate the set of induction hypotheses: The ith hypothesis -θi , condi , repli . is generated as: i. Set up constraint equations CE = {ti = s!i | 1 ≤ i ≤ k}. Solve CE using LA as before, with context {condc , Eµ }. Let c!c be the new feasibility constraints obtained and let σi be the new substitution obtained. ii. Use σi and c!c to compute θi , condi and repli as before. No solution corresponds to the ith hypothesis not being generated.

7.2

Merging induction schemes using semantics

As discussed in section 3.1, one of the crucial preconditions for merging two induction cases is to have syntactically unifiable substitutions for the common induction variable(s); the merged induction case is obtained from the mgu of these substitutions. If the definitions involved are not constructor-based or if there are relations on the constructors (E is not empty) then the merged scheme obtained by the above described procedure using syntactic unification need not be complete. For such cases, the substitutions for the common induction variables in the induction cases have to be semantically unified (with respect to =E ).9 For (P5 ), for instance, the induction schemes suggested by divides(2, x) and that suggested by divides(2, s(x)) cannot be merged using syntactic unification. However these two induction schemes can be merged if we use linear arithmetic to reconcile these substitutions. The linear arithmetic procedure is again used to perform the semantic unification of the substitutions of the common induction variables of the schemes being merged. For soundness, the same semantic ordering )LA must be used to prove the termination of the definitions of the functions from which the schemes are derived. The merging 8

σ({s1 , · · · , sk }) = {σ(s1 ), · · · , σ(sk )}. This can be done provided unification modulo =E is decidable and finitary. Further, merged induction cases corresponding to each mgu of the substitutions of the common induction variables need to be generated for the merged scheme to be complete. 9

algorithm is essentially the same as in section 3.1 except that LA is used for unification instead of a standard unification algorithm over the empty theory. We illustrate the merging algorithm by merging the scheme for divides(2, x) with the scheme for divides(2, s(x)). The first element of the scheme for divides(2, x) merges only with the first element of divides(2, s(x)) to give: --{x → 0}, {}, {1 ← divides(2, 0), 2.1 ← divides(2, s(0))}., {}..

The second element of the scheme for divides(2, x) merges only with the second element of divides(2, s(x)) to give: --{x → 1}, {}, {1 ← divides(2, 1), 2.1 ← divides(2, 2 + 0)}., {}.. Note that the hypothesis -{x → v ! − 1}, {v ! ≥ 1}, {2.1 ← divides(2, v ! )}.. is discarded since the constraint equations of the induction conclusions of the two elements being merged are {x = 1, x = v ! + 1} which implies v ! = 0 and the condition v ! ≥ 1 governing the hypothesis is unsatisfiable. Finally, the third element of divides(2, x) merges only with the second element of divides(2, s(x)) to give: --{x → 2 + v}, {}, {1 ← divides(2, 2 + v), 2.1 ← divides(2, 2 + (v + 1))}, {-{x → v}, {}, {1 ← divides(2, v), 2.1 ← divides(2, v +1)} .}.. To obtain the above merged induction scheme element, we reconcile the two substitutions of x: x → v + 2 and x → v ! + 1 producing v ! = v + 1. The merged induction scheme obtained is:

{--{x → 0}, {}, {1 ← divides(2, 0), 2.1 ← divides(2, s(0))}., {}., --{x → 1}, {}, {1 ← divides(2, 1), 2.1 ← divides(2, 2 + 0)}., {}., --{x → 2 + v}, {}, {1 ← divides(2, 2 + v), 2.1 ← divides(2, 2 + (v + 1))}., {-{x → v}, {}, {1 ← divides(2, v), 2.1 ← divides(2, v + 1)}.}.}. Performing induction based on this scheme leads to two base cases and an induction step case. The first base case, divides(2, 0) = not(divides(2, s(0))), is proved using rules 1 and 2 in the definition of divides. The second base case becomes divides(2, 1) = not(divides(2, 2 + 0)) which is established by the rules 2 and 3 of the definition of divides. In the induction step, the conclusion is: divides(2, 2 + v) = not(divides(2, 2 + (v + 1))), with the hypothesis: divides(2, v) = not(divides(2, v + 1)). The conclusion is reduced by rule 3 to divides(2, v) = not(divides(2, v + 1)), to which the hypothesis is applicable. The reason for keeping replacements for subterms being used for generating induction schemes should be evident. In the above conclusion, the subterm at position 1 is already in the form divides(2, 2 + v) so that rule 3 in the definition of divides is directly applicable; a similar remark applies for the subterm divides(2, 2 + (v + 1)) at position 2.1.

8

Applications

We have been experimenting with the cover set approach for mechanizing induction for nearly 7 years. Soon after a preliminary version of the approach was implemented in RRL, we were able to prove

many nontrivial properties about numbers, lists and sequences, including many examples from Boyer and Moore’s first book. In [15], we discussed a proof of unique prime factorization theorem using the cover set method. Since then, Hantao Zhang and his students have proved many nontrivial properties about mathematical structures including Ramsey’s theorem, Chinese remainder theorem, binomial theorem, Gilbreath’s card trick, etc. My student Subramaniam proved the arithmetic-geometric mean theorem, soon after it was presented as a challenge problem by Alan Bundy in an induction workshop in Washington, D.C. in August, 1993. We have also used the cover set method for analyzing specifications, reasoning about them as well as proving many properties of programs on numbers, strings, and sequences written in the Tecton system. A particular mention must be made of our recent work on algorithms using powerlists, a data structure proposed by Misra for combining parallelism and recursion [13]. We have done proofs of properties of parallel algorithms specified recursively using powerlists [10]. Over the last 3-4 months, we have been doing proofs of properties of hardware descriptions – different types of generic adders, including carry lookahead and carry save [11], as well as different types of multiplier circuits including Wallace multiplier circuit as well as a 7-3 multiplier circuit. We have been very pleased to observe that the proofs generated by RRL on these algorithms and hardware descriptions using powerlists closely resemble well-crafted proofs done by Misra and his students. In collaboration with Leo Bertossi’s group in Chile, we have been exploring the use of the cover set method for verifying invariant properties of deductive bases using an approach for a partial solution to the frame problem proposed by Reiter [1].

Acknowledgments: I thank Hantao Zhang for coming up with the idea of a cover set method during his dissertation research, implementing it in RRL and demonstrating to me, its effectiveness. Since the original implementation, Xumin Nie and Mahadevan Subramaniam have contributed to the further development of the cover set approach. Nie integrated Fourier’s decision method for manipulating linear inequalities into the rewriting mechanism of RRL. Subramaniam has continued to extend the use of Presburger arithmetic to make the cover set more effective as well as has been developing heuristics to predict failed proof attempts if certain induction schemes proposed by the cover set approach are pursued.

References [1] L. Bertossi, J. Pinto, P. Saez, D. Kapur and M. Subramaniam, Proving Integrity Constraints with a Rewrite Rule based Theorem Prover, Preliminary draft, Department of Computer Science, State University of New York at Albany, Jan. 1995. [2] R.S. Boyer and J S. Moore, A Computational Logic. ACM Monographs in Computer Science, 1979. [3] R.S. Boyer and J S. Moore, A Computational Logic Handbook. New York: Academic Press, 1988. [4] N. Dershowitz, “Termination of rewriting,” J. of Symbolic Computation 3, 69-116, 1987. [5] D. Kapur, D.R. Musser, and X. Nie, “An Overview of the Tecton Proof System,” Theoretical Computer Science Journal, Vol. 133, October, 1994, 307-339.

[6] D. Kapur and X. Nie, “Reasoning about numbers in Tecton,” Proceedings of the 8th International Symposium on Methodologies for Intelligent Systems, (ISMIS’94), Charlotte, North Carolina, October 1994, 57-70. [7] D. Kapur and M. Subramaniam, “Using linear arithmetic procedure for generating Induction Schemes,” in Proc. Foundations of Software Technology and Theoretical Computer Science (FSTTCS-14), P.S.Thiagarajan (ed.), LNCS, Springer Verlag, Dec. 1994. [8] D. Kapur and M. Subramaniam, New Uses of Linear Arithmetic in Inductive Theorem Proving. Department of Computer Science, State University of New York at Albany, August 1994. To appear in J. Automated Reasoning. [9] D. Kapur and M. Subramaniam, Failure Analysis of Induction Schemes and the Role of Generalization. Preliminary draft, Department of Computer Science, State University of New York at Albany, September 1994. [10] D. Kapur and M. Subramaniam, “Automated reasoning about parallel algorithms using powerlists,” Proc. of AMAST’95, LNCS, Springer Verlag, July 1995. [11] D. Kapur and M. Subramaniam, Mechanical Verification of Adder Circuits using Powerlists. Preliminary draft, Department of Computer Science, State University of New York at Albany, March 1995. [12] D. Kapur and H. Zhang, “An Overview of Rewrite Rule Laboratory (RRL),” J. of Computer and Mathematics with Applications, 29, 2, 1995, 91-114. [13] J. Misra, “Powerlists, ” ACM Tran. on Programming Languages and Systems (TOPLAS), Nov. 1994. [14] H. Zhang, Reduction, superposition and induction: automated reasoning in an equational logic. Ph.D. Thesis, Department of Computer Science, Rensselaer Polytechnic Institute, Troy, NY, 1988. [15] H. Zhang, D. Kapur, and M.S. Krishnamoorthy, “A mechanizable induction principle for equational specifications,” Proc. of Ninth International Conference on Automated Deduction (CADE9), Argonne, IL. Springer-Verlag LNCS 310, 250-265, 1988.