Compilation Techniques for Associative-Commutative Normalisation

We consider the problem of term normalisation modulo associative-commutative (AC) theories and describe several techniques for compiling many-to-one AC matching and reduced term construction. The proposed method, illustrated on three examples, is based on compact bipartite graphs, and is designed for working very efficiently on specific classes of AC patterns. Our experimental results provide strong evidence that compilation of many-to-one AC normalisation is a useful technique for improving the performance of algebraic programming languages.


Introduction
Term rewriting techniques are used in software development, compiler generation, computer algebra, theorem provers, more recently in constraint solving [6].Several programming languages (for example ASF+SDF [12], OBJ [7], or Maude [3]) use term rewriting as the execution engine of their programs.
Algebraic structures often involve axioms like associative-commutative (AC) properties of function symbols, that cannot be used as terminating rewrite rules, but instead can be handled implicitly by working with congruence classes of terms.For practical implementation purposes, representatives of these congruence classes are chosen, and the matching step of term rewriting is performed by special matching algorithms, specific to the equational theories in use.An important case in practice is the case of associative-commutative theories.
In this paper, we present several compilation techniques developed for an extension of the ELAN compiler [15] in order to handle AC function symbols.Experiments have shown speed-ups of the ELAN interpreter up to 2,000 times when rewriting with AC function symbols.
In section 2, we give the useful preliminary definitions and describe the term data structure used by the compiler.In section 3, we explain the fundamental ideas to compile leftmost-innermost normalisation, first without AC symbols.We then explain the additional difficulties brought by the AC case.In section 4, we propose several new techniques to compile AC normalisation in an efficient way.In section 5, we evaluate the performance of our compiler and compare it with other existing systems.Concluding remarks are given in section 6.

Basic notions
We consider terms T F; X built from a given finite set F of function symbols and a set X of variables.T F is the set of ground terms (without variables).We denote the set of variables occurring in a term t by V art.
Given a binary function symbol u, let AC be the set of associativity and commutativity axioms ux; uy;z = uux; y; z and ux; y = u y;x: Theory and Practice of Algebraic Specifications ASF+SDF'97 The notation u AC emphasises that u is such an AC function symbol that satisfies these two axioms.F ; is the subset of F made of function symbols which are not associative-commutative, and are called free function symbols.A term is said to be syntactic if it does not contain any AC function symbol.
Positions in a term are represented as sequences of integers.The empty sequence denotes the top-most position.
A term t is said to be linear if no variable occurs more than once.
A substitution is an assignment from X to T F; X , written = fy 1 7 !t 1 ; : : : ; y k 7 !t k g.It uniquely extends to an endomorphism of T F; X .
A conditional rewrite rule is a triple of terms denoted c l !r such that l;r 2 T F ; X , c is a boolean term, and V arc V arr V arl.c is called the condition, l the left-hand side or pattern and r the right-hand side.A rewrite rule is said to be syntactic if the left-hand side is a syntactic term.
We assume the reader to be familiar with basic ideas of term rewriting and AC theories.Full definitions can be found for instance in [14,11].

Canonical form
Canonical forms are terms that are representatives of their AC congruence class.
We allow AC function symbols to be varyadic.Identical arguments of an AC function symbol are grouped together.So any argument of an AC function symbol has a multiplicity which is a positive integer, denoted by a superscript.
Canonical form computation can be defined as a function CF : T F;X !T F ; X that chooses, for each term t, a unique representative of its congruence class.In order to recursively compute canonical forms, we assume given a total ordering on the set of function symbols F and variables, and extend it to terms in canonical form as follows.For terms that are just variable or constant symbols, CF is the identity function and the total ordering is the given ordering on symbols.For terms in canonical form with different top symbols, the total ordering on canonical form is given by the ordering on their top symbols.The canonical form is obtained by flattening nested occurrences of the same AC function symbol, recursively computing the canonical forms and sorting the subterms, and replacing k identical subterms by a single instance of the subterm with multiplicity k.These canonical forms and term ordering were introduced in [10].For more details, see [5].
Given an AC function symbol u AC , consider for example t = u AC u AC t 1 ; t 2 , t 3 , u AC t 4 ; t 5 where no t i has u AC as top symbol.Suppose that CF t 1 = CF t 5 ,CFt 3 = CF t 4 and CF t 1 CF t 2 CF t 3 .Then CF t = u AC CFt 1 2 ;CFt 2 ;CFt 3 2 .

Term representation
The fundamental object in an algebraic programming language is the first-order term.In implementations, the representation of first-order terms is generally based on trees.An alternative representation of terms which is linear rather than tree-like has been proposed by Jim Christian [2].Those flatterms, represented by a doubly-linked list data structure, yield in practice simpler and faster traversal algorithms than the conventional tree representation.In our compiler, AC function symbols may be varyadic and it must be possible to share subterms.The flatterms representation is not compatible with this last requirement because subterms stored in the doubly-linked list cannot be shared.The last constraint is that no time-overhead is wanted when no AC symbol is used.
To satisfy those constraints, two different tree based representations are used.Subterms of free function symbols are stored in an array, while subterms of AC function symbols are stored in a simply-linked-list.The representation of terms fgb; a ; g b and u AC gb; a ; g b is illustrated in the two first pictures of the following figure: This data structure can be easily extended to represent terms in canonical form.The third picture illustrates how multiple copies of equivalent terms are represented by storing their multiplicity in list-cells.

Compiling leftmost-innermost normalisation
In order to present the currently known compilation techniques, we first briefly introduce in this section the method used for compilation of leftmost-innermost normalisation in the case of syntactic rules in the ELAN compiler [15].Then we sketch a few techniques used for AC normalisation and the related difficulties.

Normalisation with syntactic rules
The general idea of the ELAN compiler is to transform a given ELAN program (a conditional rewrite rule system) into a C program, which takes a ground input term s in internal representation (usually called subject) and computes a normal form of s.
Given a set of conditional rules, a normalisation step begins by selecting a rule that can be applied to the subject.A successful matching instantiates the variables of the left-hand side, and the condition is then evaluated.If the condition is evaluated to false, another rule is selected.Then the normalisation process proceeds by cutting the part of the input term corresponding to the instantiated left-hand side of the rewrite rule and finally constructing the reduced term by plugging the instantiated right-hand side of the rule.If no rule is applicable, a special function match fail is called.This function returns the current subject as normal form.Several refinements of this general schema are possible and have been implemented in the ELAN compiler.

Many-to-one syntactic matching
The first possible improvement concerns the compilation of the matching algorithm.It consists in regrouping rules with the same top symbol on the left-hand side.For each functional symbol f of arity n, the collected rules are compiled into a C function funfof n arguments.This function when applied to the terms t 1 ; : : : ; t n , returns the reduced form of the term ft 1 ; : : : ; t n , according to the leftmost innermost normalisation strategy.All rewrite rules are known at compile time.Matching of their left-hand sides to an unknown input term can be pre-compiled using some existing algorithm [9,8].The resulting code gives the set of applicable rules represented in a very efficient manner by a bitset.Since we are interested in leftmost innermost evaluation, the construction of the reduced term can be compiled into nested calls of different funffunctions.

Reusing parts of terms
Another improvement comes from the Berlin project OPAL [4].The main idea is to reuse parts of left-hand sides of rules to construct the right-hand sides when applying a rewrite rule.However this technique requires to use tags or reference counters in order to indicate whether a subterm is shared by several terms.More details can be found in [15].
Theory and Practice of Algebraic Specifications ASF+SDF'97

Associative-Commutative normalisation
Associative-commutative rewriting is a more complex mechanism and it is known since 1987 that AC matching is NP-complete [1].Let us focus now on difficulties added by AC theories.

One-to-one general AC-matching
Given a ground subject s and a set of rules r 1 ; : : : ; r n , the first thing to do is to select a rule r i and try to apply it at the top position of s.To check if a selected rule is applicable, a matching algorithm is needed.In the syntactic case (when all rules are syntactic), it is quite simple.Starting from the root of s and the left-hand side of r i it consists in checking that function symbols from the pattern appear at the same position in s.Suppose that fx; gha; y; z is the pattern and fa; gha; b; c is the subject.There is a trivial substitution fx 7 !a; y 7 !b; z 7 !cg such that the pattern matches the subject.
For the AC case, the problem becomes more difficult, since different permutations of s have to be considered.For instance, in the previous example, if f is AC, the substitution fx 7 !c; y 7 !b; z 7 !ag is another solution to the matching problem.Given a ground subject s = u AC s 1  1 ; : : : ; s p p , and a pattern u AC p 1 ; : : : ; p n , bipartite graphs are usually used to represent the matching problems: an edge is built between p j and s i if p j matches s i .
Associative-commutative matching can be presented in four steps [5]: 1. convert pattern and subject to their canonical-forms; 2. decompose the matching problem into a hierarchy of bipartite graphs; 3. find a compatible set of solutions to the bipartite graph matching problems and construct a Diophantine equational system which encodes the constraints on the remaining unbound variables; 4. solve the Diophantine equational system to get a matching substitution.
This algorithm is quite general.Each time it tries to apply a rule, it has to build and solve the hierarchy of bipartite graphs and the Diophantine equational system.This approach is very expensive in memory management because many dynamic data structures have to be built and deleted.
The method described above is efficient when a complex matching problem has to be solved (many nested AC operators and a lot of non-linearity).In contrast to theorem proving, where rewrite steps may involve complex nonlinear patterns and relatively small subjects, in algebraic programming, we usually have a lot of simple linear patterns and huge subjects.

Reduced term construction
If the selected rule can be applied to the subject, the only thing to do consists in transforming the subject.As in the syntactic case, this is done by replacing the current subject by the right-hand side of the selected rule in which all variables have been instantiated by the substitution.This substitution is usually built during the AC matching phase.But an additional difficulty comes with conditional rewrite rules.In conditional rewriting, conditions have to be normalised and compared to true before building the right-hand side.If a condition is evaluated to false, this means that the current substitution is not compatible with this condition.As long as there is a solution to the matching problem for which the condition is not satisfied, another solution has to be found and extracted from the matching problem.If no solution is remaining, the selected rule is no longer a good candidate and another one is selected.Conditional rewriting requires matching problems to be solved in a particular way: the first solution has to be found as fast as possible, and the others have to be found "on request".It is not necessary to compute immediately all solutions to the matching problem.
The method presented in section 3.2.1 is correct but quite inefficient in practice.The matching algorithm is too general for the usual cases, but it seems to be very difficult to get a better equivalent algorithm.The main drawbacks of the previous approach are: one-to-one matching is too slow in practice; too many data structures depending on the non-static subject size have to be managed during runtime; the reduced term construction phase is not sufficiently optimised and it is not connected with the matching phase.
In this section we propose some new techniques that give significant speed-ups on problems met in practice.Our solutions are based on the fact that all rewrite rules are known before the compilation phase.So we can do particular treatments at compile time such as many-to-one pre-compilation and static data structure constructions.In addition, our approach consists in designing particular algorithms for frequently occuring cases.We did an inspection of the most useful AC patterns used in ELAN, and extracted the pattern classes presented in 4.1.Specific compilation techniques have been developed for those classes of patterns.Matching problems involving other patterns can be solved with the general matching algorithm sketched in section 3.2.1.

Pattern classes
Compilation algorithms presented in this section only work on a subset of patterns in T F; X .Here, we describe by successive refinements several pattern classes that correspond to families of frequently used left-hand sides in rewrite rule programming.
Recall that F ; is the set of free function symbols, F AC the set of AC function symbols and X the set of variables.
The pattern class C 0 contains flat terms in canonical form with one AC function symbol on top and two variables with multiplicity greater than 1 immediately under this AC function symbol.

Definition 1
The pattern class C 0 consists of terms t in canonical form of the form t = u AC x ; y with u AC 2 F AC , x; y 2 X with x 6 = y, and ; integers 1.
The pattern class C AC ' and one variable 'y'immediately under v AC .This term is in the class C 1 .By adding a free function symbol f of arity 3 at the top position, a term u AC y 1 ; y 1 ; y 2 of the class C 0 , and a variable z, the term: fv AC y;gs 1 ; : : : ; s m ; z ; u AC y 1 ; y 1 ; y 2 becomes a member of the class C 2 .By adding a second level AC function symbol w AC and a variable x, the term w AC x; fv AC y;gs 1 ; : : : ; s m ; z ; u AC y 1 ; y 1 ; y 2 becomes a member of the class C 3 .

Many-to-one AC-matching
In order to minimise the number of matching attempts, the technique used in syntactic many-to-one matching can be adapted to the AC case.
Given a set of rewrite rules, the method consists in regrouping subterms with the same AC top function symbol.A many-to-one matching algorithm for this set of subterms is used to build a particular bipartite graph called Compact Bipartite Graph and described below.Given a subject, the purpose of a compact bipartite graph is to encode in only one data structure all matching problems relative to the given set of rewrite rules.
Instead of repeatedly selecting a rule, building a bipartite graph, solving it, selecting another rule, and so on. . .until conditions are evaluated to true, this compact data structure represents all bipartite graphs that the general algorithm has to build, in a more efficient way.The speedup comes from the fact that common syntactic subterms are matched only once, even if they appear in several rules.
The method presented here is related to discrimination nets [2] and AC discrimination nets [13].AC discrimination nets do similar improvements without any limitation on pattern structure.However the automaton built to encode the discrimination net is not really compiled.It is stored in an abstract data structure that is interpreted to simulate the automaton execution.In the approach proposed here, the automaton is directly coded in an imperative language like C. No intermediate abstract data structure is built to represent the automaton.Although the two approaches are not easily comparable, AC discrimination nets seem to be a good choice to implement theorem provers whose pattern database can be modified during computations.On the contrary, our approach seems to be promising to implement algebraic programming languages in an efficient way.

Compact Bipartite Graph
Given a set of rewrite rules, syntactic subterms p 1 ; : : : ; p n of their left-hand sides with the same AC top function symbol u AC are grouped together and compiled into a function (f unu AC ) that implements the many-to-one syntactic matching described in section 3.1.1.Given a subject s = u AC s 1  1 ; : : : ; s p p , this function returns a bitset for each s i which encodes possible matches.The j th bit is set to 1 if p j matches s i .This information is used to build the compact bipartite graph: an edge is built between p j and s i if p j matches s i .
Let us illustrate this construction on an example.Given the two rewrite rules, u AC fa; x; f y;gb !r 1 , and u AC z;fa; x 0 ; g a !r 2 , an analysis of subterms with the same AC top function symbol u AC gives three distinct non-variable subterms up to variable renaming: p 1 = fa; x, p 2 = fy;gb and p 3 = ga.Variable subterms (z in the previous example) are not involved in compact bipartite graph construction.They are instantiated in the reduced term construction phase described in 4.4.Let us consider the subject s = u AC fa; a 1 ; f a; c 2 ; f b; gb 3 ; f g c ; g b 4 ; g a 5 : After trying to match all subterms fa; a, fa; c, fb; gb, fgc; g b and ga by p 1 ; p 2 and p 3 , the following compact bipartite graph is built: Theory and Practice of Algebraic Specifications ASF+SDF'97 fa; x fy;gb ga fa; a fa; c fb; gb fgc; g b ga 1 1 0 0 0 0 0 1 1 0 0 0 0 0 1 The current compact bipartite graph is represented by three bitsets.The first one: 11000, means that the corresponding pattern p 1 matches only the two first subterms: fa; a and fa; c, and similarly for the other ones.
In order to normalise the subject, a rule has to be selected, say the first one: u AC fa; x; f y;gb !r 1 .The bipartite graph that should have been created by the general method can be easily constructed by extracting edges that are joining p 1 and p 2 to subject subterms.This is done by selecting two bitsets: 11000 and 00110, which gives the following "classic" bipartite graph: fa; x fy;gb ga fa; a fa; c fb; gb fgc; g b ga 1 1 0 0 0 0 0 1 1 0 This bipartite graph has four solutions: fx 7 !a; y 7 !bg, fx 7 !a; y 7 !gcg, fx 7 !c; y 7 !bg and fx 7 !c; y 7 !gcg.If the selected rule has some conditions not compatible with those four substitutions, another rule has to be selected (here the second one): u AC z;fa; x; g a !r 2 .
The new associated bipartite graph is built with only two selected bitsets: 11000 and 00001.fa; x fy;gb ga fa; a fa; c fb; gb fgc; g b ga 1 1 0 0 0 0 0 0 0 1 Note that common syntactic subterms are matched only once, even if they appear in several rules.Moreover, there is no need to flatten the subject because it is supposed to be in canonical form by construction and we will see in 4.5 how to maintain this condition.
To handle patterns of class C 3 , a hierarchy of bipartite graphs has to be built.Thanks to the construction of the class C 3 , the hierarchy is limited to only two levels of bipartite graphs.For each edge of the graph that joins two AC function symbols, an AC subproblem is attached.This hierarchy is represented by a matrix of bipartite graphs where rows correspond to subject subterms, and columns correspond to patterns p i .Before selecting another rule (from the compact bipartite graph), the two-level-hierarchy of bipartite graphs has to be solved.

Theory and Practice of Algebraic Specifications ASF+SDF'97
Compilation Techniques for Associative-Commutative Normalisation

Reduced term construction
Before constructing the reduced term, a substitution which encodes a solution to the matching problem has to be built.In the syntactic case, this substitution is easily built during the matching phase, since there is at most one solution, so static variables (of the implementation language) can be used to store instantiations of variables occurring in the pattern.In the AC case, the problem is more complex.There may be several different instantiations for each variable (as a result of permutations).Combinations of variables occurring in the two possible levels can produce a number of solutions exponential in the subject size.It is not realistic to store all those substitutions in the bipartite graph in order to use them for constructing the reduced term.
Furthermore, all this work is not necessary when the first selected rule is applied because all pre-computed substitutions are deleted and a lot of work is wasted.Our approach consists in building the substitution only when a solution is found.Each solution stores the selected rule and a list of subject subterms (s i ) matched by pattern subterms (p i ).
All pattern subterms are known at compile time, positions of their variables are static and can be pre-computed.It is not difficult to find a corresponding position in a given subject subterm and to extract the variable instantiation.In the last given example, u AC z;fa; x; g a !r 2 is the selected rule and the first solution of the bipartite graph indicates that fa; x matches fa; a.The static position of x ( :2, second argument of fa; x) is sufficient to find its instantiation (a, second argument of fa; a).
The pattern structure restriction is such that only one variable may appear directly under each AC function symbol, except for patterns of the form u AC x; y for which a special algorithm is used.To instantiate a single variable, there is no need to construct a Diophantine equational system: all unmatched subject subterms are captured by this variable.For completeness of AC rewriting, extension variables have to be added.Those variables store the context and allow to do rewrite steps in subterms.
In the syntactic case, all variable instantiations are irreducible by construction.Nested function calls are such that before a match phase, each subterm is in normal form wrt. the rewrite rule system.This is no longer the case in AC rewriting: for instance, in our previous example, the variable z can be instantiated by u AC fa; c; f b; gb; fgc; g b which is reducible by the first rule u AC fa; x; f y;gb !r 1 .So instantiations of variables that appear under an AC function symbol have to be normalised before using them to build the right-hand side.
Once a substitution is found, the right-hand side is built as it is done in the syntactic case: subterms of the left-hand side can be re-used to build the reduced term and non-linear right-hand sides share their common subterms.

Maintaining canonical forms
The compact bipartite graph construction (matching phase) supposes that both pattern and subject are in canonical form.Each subterm is also in canonical form and must be irreducible wrt. the rewrite rule system.A basic idea could be to flatten and compute the canonical form after each right-hand side construction, but the cost of this approach is very high.Note that all subterms that instantiate a variable are, by construction, in canonical form.It is not necessary to re-compute their canonical form more than once.Our approach consists in maintaining this canonical form during the reduced term construction.Whenever a new term t is added as a subterm of s = u AC s 1  1 ; : : : ; s n n , if an equivalent subterm s i already exists, its multiplicity is incremented, else, the subterm t (which is in normal form by construction) is inserted in the list s 1  1 ; : : : ; s n n at a position compatible with the chosen ordering.If t has the same AC top symbol u AC , a flattening step is done and the two subterm lists are merged with a merge sort algorithm.Definition 5 Let mcf be defined for two terms s = u AC s 1  1 ; : : : ; s n n and t = vt From the definition of mcf, it is easy to get: Proposition 1 Let s = u AC s1 1 ; : : : ; s n n and t be two terms in canonical form.The function mcf applied to s and t returns the canonical form of u AC s 1  1 ; : : : ; s n n ; t .As a consequence, the bottom-up construction of a term, using the mcf function, ensures that the resulting term is in canonical form.

Experimental results
To illustrate the power of our compilation techniques, let us consider three examples that make heavy use of AC normalisation.Those examples have been compiled with the new ELAN compiler, which is implemented with approximatively 6,000 lines of Java.A runtime library support has been implemented in C to support basic term and AC matching operations.This library contains more than 6,000 lines.
We compared our implementation with three AC rewriting systems: OBJ [7], Maude [3] and of course the ELAN interpreter.The number of applied rewrite rules is difficult to compare because it depends on the internal strategy chosen and on the method used for counting applied rules 1 .Two different architectures were used to run benchmarks: a Pentium Pro 200 Linux (Intel) and a Sun Ultra-Enterprise Solaris 5.5.1 (Sparc).

A propositional prover
This first example implements the two basic AC operators and, xor, and four syntactic rules that transform not, implies, or and if functions into nested calls of xor and and.singles _ doubles _ triples _ set0 _ set25 _ set50 finish !set50 _ doubles + turn + turn The rule turn !: : : means that with one dart, a single, a double or a triple can be hit.Bad players can miss the target (0 point) and lucky players can hit a centre (25 or 50 points).The problem consists in evaluating finish.
Rules for score counting are given in the following rewrite system where _, + and are AC functions symbols.x; y; i and j are variables. x

Bool 3
This last example implements computation in a 3-valued logic bool3.The rewrite system is defined by the following rules: x + 0 !x x + x + x !0 x 0 !0 x 1 !x x x x !x x + y z! x z + y z 2 !1 + 1 andx; y !x x y y + 2 x x y + 2 x y y + 2 x y orx; y ! 2 x x y y + x x y + x y y + x y + x + y notx ! 2 x + 1 The problem consists in normalising anda 1 ; : : : ; a 8 and notornota1; : : : ; n o t a 8 to prove their equality.

Concluding Remarks
In this paper, we have proposed a new approach to compile AC rewrite rule systems in an efficient way, thanks to the design of optimised algorithms to solve AC matching problems in the case of several specific classes of patterns.
We have introduced a new data structure, called Compact Bipartite Graph, and used it to compile many-to-one AC matching.A compact bipartite graph encodes, in only one data structure, all matching problems relative to a set of rules.
Many techniques implemented in the previous compiler [15] have been extended and re-used in the current implementation: an efficient syntactic many-to-one matching, shared term data structures, and the re-use of parts of the left-hand sides to construct the reduced term.
Several examples have been implemented and results are promising.We feel that the method can yet be improved by designing a new algorithm for matching, optimised for generating a single solution to matching problems.
Further work consists in extending presented techniques to other theories (A, ACI, AC1, AC0) and breaking the C 3 class restriction to extend algorithms to T F; X .
Theory and Practice of Algebraic Specifications ASF+SDF'97 , u AC 2 F AC , x 2 X and t 1 ; : : : ; t n 2 T F ; ; X nX .The third class contains terms from classes C 0 and C 1 , and terms built by composition with free function symbols.Definition 3 The pattern class C 2 is the smallest set of terms in canonical form that contains C 0 and C 1 , and such that ft 1 ; : : : ; t n is in C 2 , if f 2 F ; , t 1 ; : : : ; t n 2 C 2 and all the t i have disjoint sets of variables.The fourth class extends the previous class to two levels of AC function symbols.The pattern class C 3 is the set of terms t in canonical form such that: t = u AC t 1 ; : : : ; t n with u AC 2 F AC and t 1 ; : : : ; t n 2 C 2 ; or Consider the term v AC y;gx 1 ; : : : ; x m where x 1 ; : : : ; x m are variables.It contains only one AC function symbol 'v 1 contains linear terms in canonical form that have only one AC function symbol on top and at most one variable immediately under this AC function symbol.Definition 2 The pattern class C 1 consists of linear terms t in canonical form such that: t 2 T F ; ; X nX ; or t = u AC t 1 ; : : : ; t n , u AC 2 F AC and t 1 ; : : : ; t n 2 T F ; ; X nX ; or t = u AC x; t 1 ; : : : ; t n t = u AC x; t 1 ; : : : ; t n with u AC 2 F AC , t 1 ; : : : ; t n 2 C 2 , x 2 X and x does not belong to the sets of variables of t 1 ; : : : ; t n .Theory and Practice of Algebraic Specifications ASF+SDF'97 Compilation Techniques for Associative-Commutative Normalisation there exists i in 1::n such that 8j i; s j t and 8j i; t s j :

Compilation Techniques for Associative-Commutative Normalisation 5.2 A score counting problem
The rewrite system is defined by the following rules:The computation consists in normalising a huge term and comparing the result to .Results are given in the following table:The second example implements a score counting problem.Suppose you want to play darts.The dartboard is divided by wires into 20 equals segments, each numbered from 1 to 20 and contains two distinct centres: the 25 ring and the Bull's-eye (50).Some places count double(2, 4,..., 40)or triple(3, 6,..., 60).Rules are simple: to begin a play, you need to shoot the Bull's-eye or a double, then you have two darts.The problem consists in listing all possible scores.The following rewrite rules describe the game rules: Results are given in the following table:

Compilation Techniques for Associative-Commutative Normalisation
Results are given in the following table:Theory and Practice of Algebraic Specifications ASF+SDF'97