Repeated Recursion Unfolding for Super-Linear Speedup within Bounds
aa r X i v : . [ c s . P L ] S e p Repeated Recursion Unfolding for Super-LinearSpeedup within Bounds
Thom Fr¨uhwirthUlm University, Germany [email protected]
September 14, 2020
This is the full version of a paper presented at the 30th International Symposiumon Logic-Based Program Synthesis and Transformation (LOPSTR 2020).
Abstract
Repeated recursion unfolding is a new approach that repeatedly un-folds a recursion with itself and simplifies it while keeping all unfoldedrules. Each unfolding doubles the number of recursive steps covered.This reduces the number of recursive rule applications to its logarithmat the expense of introducing a logarithmic number of unfolded rules tothe program.Efficiency crucially depends on the amount of simplification inside theunfolded rules. We prove a super-linear speedup theorem in the best case,i.e. speedup by more than a constant factor. Our optimization can lowerthe time complexity class of a program. In this paper, the super-linearspeedup is within bounds: it holds up to an arbitrary but chosen upperbound on the number of recursive steps.We also report on the first results with a prototype implementationof repeated recursion unfolding. A simple program transformation com-pletely removes recursion up to the chosen bound. The actual runtimeimprovement quickly reaches several orders of magnitude.
Keywords.
Program Transformation, Program Optimization, Super-Linear Speedup, Recursion, Speedup Theorem, Time Complexity.
In the context of rule-based and logic programming, unfolding is the programtransformation that replaces a call (goal) in the body of a rule by the bodyof a rule whose head is matched by the goal. This saves a rule application atruntime. More importantly, the resulting code can be simplified for efficiency.1 xample 1 (Summation)
Consider the following simple recursive programwritten in CHR (Constraint Handling Rules). It adds all numbers from to n . r : sum ( N, S ) ⇔ N > | S := N + S , sum ( N − , S sum ( N, S ) ⇔ N = 1 | S = 1 . Head, guard and body of a rule are separated by ⇔ and | , respectively. Therules can be understood as a procedure definition for sum , each rule covering acase. When a call matches the head of a rule and the guard condition holds, thebody of the rule is executed. In CHR code, upper case letters stand for logicalvariables.Unfolding the recursive rule with itself will result in r : sum ( N, S ) ⇔ N > , N − > | S := N + S , N ′ = N − , S N ′ + S ′ ,sum ( N ′ − , S ′ ) , which can be simplified to r : sum ( N, S ) ⇔ N > | S := 2 ∗ N − S ′ , sum ( N − , S ′ ) . Note that this rule r cannot replace the original recursive rule because it onlyapplies in case N > . It behaves like applying the original rule r twice. It savescomputation time, because we only need about half as many recursive steps aswith the original rule alone. Since the simplification of the unfolded rule resultsin code of similar size and time complexity as the original rule, we can expectto halve the runtime.If we would now unfold the recursive goal in rule r with rule r we haveunfolded thrice overall. We can expect a speedup of roughly three times if wereplace r by the new rule. But we can do even better than that if we keep rule r and unfold rule r with itself. The resulting rule after simplification is r : sum ( N, S ) ⇔ N > | S := 4 ∗ N − S , sum ( N − , S . This rule results in a four-fold speedup.
We can repeat this process: unfolding the newly generated recursive rulewith itself until we reach a given upper bound. We never unfold with the basecase. It is ignored. This is what we call repeated recursion unfolding . With eachunfolding, the number of original recursive steps simplified into one recursivestep of the unfolded rule will double.Given n recursive steps with the original rule and log ( n ) unfolded rulesaccording to our scheme, it is possible to have at most log ( n ) recursive ruleapplications instead of n . If the unfolded rules take not more time than theoriginal recursive rule, the time complexity class can be lowered and super-linear speedup in runtime can be achieved.For our scheme to work, we always have to apply the best, most unfoldedrule. To implement this behavior, we use another program transformation thatremoves the recursion altogether. We call this recursionless recursion .2 verview of the Paper. Section 2 introduces syntax and semantics of theCHR programming language using a single state transition.Section 3 defines our program transformation scheme of repeated recursionunfolding with simplification and proves its correctness. We will use summationas our running example.Section 4 proves that there exists a simple optimal rule application strategyfor unfolded recursions with best-case simplification that results in super-linearspeedup by lowering the time complexity classes by a factor of up to O ( n ).Section 5 introduces recursionless recursion, a transformation that providesa semi-naive implementation of optimal rule applications. We prove that theworst-case overhead of this scheme is linear in the number of unfolded rules.In Section 6 we conclude our summation example with benchmarks in ourprototype implementation. It improves time complexity from linear to constant.Another example, naive list reversal, improves from quadratic to linear complex-ity. It runs faster than the hand-optimized built-in list reversal in Prolog, theimplementation language of CHR.Finally, we discuss related work and end with conclusions. We recall the abstract syntax and the equivalence-based abstract operationalsemantics of CHR (Constraint Handling Rules) [Fr¨u09] in this section. Wealso informally describe the refined operational semantics typically realized insequential implementations of CHR.
The CHR language is based on the abstract concept of constraints.
Constraints are relations, distinguished predicates of first-order predicate logic. There aretwo kinds of constraints: built-in (pre-defined) constraints and user-defined(CHR) constraints which are defined by the rules in a CHR program. Built-inconstraints can be used as tests in the guard as well as for auxiliary computa-tions in the body of a rule. There are at least the built-in constraints true and false , syntactical equality = over finite terms and the usual relations over arith-metic expressions. Upper-case letters stand for (possibly empty) conjunctionsof constraints in definitions, lemmas and theorems.
Definition 1 (CHR Program and Rules) A CHR program is a finite setof rules. A (generalized) simplification rule is of the form r : H ⇔ C | B, where r is an optional name (a unique identifier) of a rule. The head H is aconjunction of user-defined constraints, the optional guard C is a conjunctionof built-in constraints, and the body B is a goal. he local variables of a rule are those not occurring in the head of the rule. A renaming (variant, copy) of a goal is obtained by uniformly replacing its variablesby other variables.Conjunctions are understood as multisets of their atomic conjuncts. Weoften use simple commas to denote logical conjunction to avoid clutter. A goal is a conjunction of built-in and user-defined constraints. A state is a goal. Computations in CHR are sequences of rule applications. The operational se-mantics of CHR is given by the state transition system. It relies on a structuralequivalence between states that abstracts away from technical details in a tran-sition [RBF09, Bet14].
State equivalence treats built-in constraints semantically and user-definedconstraints syntactically. Basically, two states are equivalent if their built-inconstraints are logically equivalent (imply each other) and their user-definedconstraints form syntactically equivalent multisets in this context. For example, X = A CHR transition (computation step) S r T isdefined as follows, where S is called source state and T is called target state : S ≡ V ( H ∧ C ∧ G ) false ( r : H ⇔ C | B ) ( C ∧ B ∧ G ) ≡ V TS r T where the rule ( r : H ⇔ C | B ) is a renaming of a rule from a given program P such that its local variables do not occur in G .A computation (derivation) of a goal (query) S with variables V in a program P is a connected sequence S i r i S i +1 beginning with the initial state (query) S that is S and ending in a final state (answer, result) S n or otherwise thesequence is infinite and the computation is non-terminating (diverging) . Wemay drop the reference to the rules. The relation ∗ denotes the reflexive andtransitive closure of . The goal G is called context of the rule application. It remains unchanged. Itmay be empty. Note that CHR is a committed-choice language, i.e. there is nobacktracking or undoing of rule applications. Almost all sequential CHR implementations execute queries and rule body con-straints from left to right and apply rules top-down following their textual or-der of the program. This behavior has been formalized in the so-called re-fined semantics which is a concretization of the abstract operational semantics[DSGH04].In this refined semantics, a CHR constraint in a goal can be understood asa procedure call that goes efficiently through the rules of the program. If thecurrent goal matches the head constraints of a rule and if, under this matching,the guard check of the rule holds in the current context, the rule is applicable.Given a query, the rules of the program are applied to exhaustion. When asimplification rule is applied, the matched constraints are replaced by the bodyof the rule. We recall a definition of rule unfolding in CHR, then define and prove correctnessof simplification inside rules in order to introduce repeated recursion unfolding. For correct unfolding of rules in CHR, we follow the definition of [GMTW15],where also correctness of the unfolding function is shown. This means that we5an safely add the unfolded rule to a program while preserving its semantics.In other words, a correctly unfolded rule is always redundant (but, of course, isexpected to improve efficiency). In this paper we specialize the definition to thecase of CHR simplification rules instead of arbitrary CHR rules. This simplifiesthe definition and is sufficient for our purposes.For a goal A , let vars ( A ) denote the set of variables in A . A substitutionis based on a mapping function from variables to terms θ : V → T , written inpostfix notation, such that domain of θ , the set dom ( θ ) = { X | Xθ = X } isfinite. When a substitution is applied to a goal, it is applied to all variables inthe goal. If A = Bθ , where B is a goal, we say that A is an instance of B , A matches B , and that B is instantiated .Set difference C = C \ C for built-in constraints is defined as C = { c ∈ C | CT 6| = C → c } . In words, C does not contain the constraints from C that are implied by C . Definition 4 (Unfolding) (Def. 8 [GMTW15]) Let P be a CHR program andlet r, v ∈ P be two rules whose variables have been renamed apart r : H ⇔ C | D ∧ B ∧ Sv : H ′ ⇔ C ′ | B ′ , where D is the conjunction of the built-in constraints in the body of r . Then wedefine unfold ( r, v ) = r ′ as follows. Let θ be a substitution such that dom ( θ ) ⊆ vars ( H ′ ) and CT | =( C ∧ D ) → S = H ′ θ , then the unfolded rule r ′ is: r ′ : H ⇔ C ∧ C ′′ θ | D ∧ B ∧ S = H ′ ∧ B ′ , where C ′′ θ = C ′ θ \ ( C ∧ D ) with vars ( C ′′ θ ) ∩ vars ( H ′ θ ) ⊆ vars ( H ) and CT | = ∃ ( C ∧ C ′′ θ ) . If a goal S in the body of rule r matches the head H ′ of a rule v , unfoldingreplaces S in the body of rule r by the body of rule v together with S = H ′ toobtain a new rule r ′ . In the resulting rule r ′ we also add to its guard C an in-stance of a part of the guard of rule v . This part C ′′ contains the non-redundantbuilt-in constraints that are not already implied by the built-in constraints inthe guard and body of the rule r .Note that for a correct unfolding according to the above definition, threeconditions have to be satisfied. First, CT | = ( C ∧ D ) → S = H ′ θ, means that goal S must match the head H ′ , i.e. be an instance of H ′ , in thecontext of the built-in constraints of the rule r . This condition reflects the factthat the rule v should be applicable to S .6econd, the non-obvious condition vars ( C ′′ θ ) ∩ vars ( H ′ θ ) ⊆ vars ( H )means that for correctness the variables shared between the instantiated head H ′ θ and instantiated simplified guard C ′′ θ of the rule v must also occur in H .Note that using C ′′ instead of C can make the set of variables smaller that haveto occur in H .Third, the satisfiability of the guard of the unfolded rule r ′ , CT | = ∃ ( C ∧ C ′′ θ ),ensures that the rule is nontrivial in that it has a satisfiable guard. Otherwisethe rule would never be applicable. Example 2 (Summation, contd.) We unfold the recursive rule for summa-tion with (a copy of ) itself: r : sum ( N, S ) ⇔ N > | S := N + S , sum ( N − , S v : sum ( N ′ , S ′ ) ⇔ N ′ > | S ′ := N ′ + S ′ , sum ( N ′ − , S ′ ) . Then the unfolded rule is sum ( N, S ) ⇔ N > , N − > | S := N + S , sum ( N − , S sum ( N ′ , S ′ ) ,S ′ := N ′ + S ′ , sum ( N ′ − , S ′ ) . Unfolding is correct since its three conditions are satisfied. First, sum ( N − , S is an instance of sum ( N ′ , S ′ ) , i.e. ( N > , S := N + S → sum ( N − , S 1) = sum ( N ′ , S ′ ) θ, since θ can map N ′ to N − and S ′ to S . Second, vars ( N − > ∩ vars ( sum ( N − , S ⊆ vars ( sum ( N, S )) holds since { N } ∩ { N, S } ⊆ { N, S } . Third, the new guard N > , N − > issatisfiable. Obviously we can simplify the built-in constraints of the guard and the body ofthis rule, and we will define this kind of simplification next. Speedup crucially depends on the amount of constraint simplification that ispossible in the unfolded rules. The goal is to replace constraints by semanticallyequivalent ones that can be executed more efficiently. Definition 5 (Simplification) Given a rule r of the form r : H ⇔ C | D ∧ B, here D are the built-in constraints and B are the user-defined constraints inthe body of the rule. We definesimplify ( r ) = ( H ′ ⇔ C ′ | D ′ \ C ′ ∧ B ′ ) such that ( H ∧ C ) ≡ V ( H ′ ∧ C ′ ) and ( C ∧ D ∧ B ) ≡ V ( D ′ ∧ B ′ ) , where D ′ are the built-in constraints and B ′ are the user-defined constraints inthe body of the rule and where V = vars ( H ) ∪ vars ( H ′ ) . In the given rule, we replace head and guard, and the body, respectively,by simpler yet state equivalent goals. The choice of V allows us to removelocal variables if possible, i.e those that occur only in the guard or body of therule. We temporarily add the guard C when we simplify the body to ensurecorrectness and improve the simplification.For correctness we have to show that the same transitions S T are possiblewith rule r and rule simplify ( r ). Theorem 1 (Correctness of Rule Simplification) Let r = ( H ⇔ C | D ∧ B ) be a rule and let s = ( H ′ ⇔ C ′ | D ′ \ C ′ ∧ B ′ ) be the simplified rule simplify ( r ) .For any state S and variables V , S r T iff S s T . Proof. According to the definition of a CHR transition and simplify ( r ) , weknow that S r T iff S ≡ V ( H ∧ C ∧ G ) false and ( C ∧ D ∧ B ∧ G ) ≡ V TS s T iff S ≡ V ( H ′ ∧ C ′ ∧ G ′ ) false and ( C ′ ∧ D ′ \ C ′ ∧ B ′ ∧ G ′ ) ≡ V T ( H ∧ C ) ≡ V ′ ( H ′ ∧ C ′ )( C ∧ D ∧ B ) ≡ V ′ ( D ′ ∧ B ′ ) . It suffices to show that S r T implies S s T , since the implication in theother direction is symmetric and can be shown in the same way. Hence we haveto show that there exists a goal G ′ such that S ≡ ( H ∧ C ∧ G ) ≡ V ( H ′ ∧ C ′ ∧ G ′ ) if ( H ∧ C ) ≡ V ′ ( H ′ ∧ C ′ ) and T ≡ ( C ∧ D ∧ B ∧ G ) ≡ V ( C ′ ∧ D ′ \ C ′ ∧ B ′ ∧ G ′ ) if ( C ∧ D ∧ B ) ≡ V ′ ( D ′ ∧ B ′ ) . We choose G ′ = C ∧ G . The full proof can be found in the appendix. (cid:3) Example 3 (Summation, contd.) Recall the unfolded rule sum ( N, S ) ⇔ N > , N − > | S := N + S , sum ( N − , S sum ( N ′ , S ′ ) ,S ′ := N ′ + S ′ , sum ( N ′ − , S ′ ) . For the head and guard we have that sum ( N, S ) , N > , N − > ≡ { S,N } sum ( N, S ) , N > . For the body we have that N > , N − > , S := N + S , sum ( N − , S sum ( N ′ , S ′ ) , S ′ := N ′ + S ′ ,sum ( N ′ − , S ′ ) ≡ { S,N } N > , S := 2 ∗ N − S ′ , sum ( N − , S ′ ) . Thus the rule can be simplified into the rule sum ( N, S ) ⇔ N > | S := 2 ∗ N − S ′ , sum ( N − , S ′ ) . .3 Repeated Recursion Unfolding We now define what it means to unfold a given recursive rule with itself, tosimplify it, to repeat this process, and to add the resulting rules up to a givenbound to the original program. Definition 6 (Repeated Recursion Unfolding) Let r be a recursive rule ina given program P . The unfolding of a recursive rule r is defined asunfold ( r ) = unfold ( r, r ) The repeated unfolding of a recursive rule r with simplification is a sequenceof rules r , r , . . . , r i , . . . where r = r ∈ P r i +1 = simplify ( unfold ( r i )) Let n be an upper bound on the number of recursive steps (recursion depth)for rule r . The recursively unfolded program P r,n of rule r is defined as P r,n = P ∪ ⌊ log ( n ) ⌋ [ i =1 r i Example 4 (Summation, contd.) Recall the unfolded simplified rule sum ( N, S ) ⇔ N > | S := 2 ∗ N − S , sum ( N − , S . We repeat the unfolding: sum ( N, S ) ⇔ N > , N − > | S := 2 ∗ N − S ,sum ( N − , S sum ( N ′ , S ′ ) , S ′ := 2 ∗ N ′ − S ′ , sum ( N ′ − , S ′ ) . The unfolded rule can be simplified into the rule sum ( N, S ) ⇔ N > | S := 4 ∗ N − S ′ , sum ( N − , S ′ ) . The complete program for repeated recursion unfolding sum three times is: sum ( N, S ) ⇔ N > | S := 8 ∗ N − 28 + S , sum ( N − , S sum ( N, S ) ⇔ N > | S := 4 ∗ N − S , sum ( N − , S sum ( N, S ) ⇔ N > | S := 2 ∗ N − S , sum ( N − , S sum ( N, S ) ⇔ N > | S := N + S , sum ( N − , S sum ( N, S ) ⇔ N = 1 | S = 1 . Note that for the query sum (9 , R ) we could use any of the recursive rules withthe same result. Of course the most efficient way is to use the first rule. Wewill discuss optimal rule applications in the next section. Time Complexity and Super-Linear Speedup We first show that we can save on rule applications with our recursive unfoldingscheme: we will always apply the most unfolded recursive rule to perform amaximum number of recursive steps with a minimum number of rule applica-tions. Significant speedup then crucially depends on the amount of constraintsimplification that is possible in the unfolded rules. Then we show that simpli-fication leads to super-linear speedup in the best case, i.e. a change into a lowertime complexity class. By definition of correct unfolding, the unfolded rule is redundant with regard tothe original rule. The other direction is not necessarily true. Even if the numberof recursive steps should admit the application of an unfolded rule instead ofthe original rule, it may not be possible because the guard of the unfolded rulemay be somewhat too strict. Lemma 1 (Optimal Rule Applications) Given a program P with a recur-sive rule r . Assume that the unfolded rules in the unfolded program P r,n satisfythe following condition: If a rule r i with i < log ( n ) can perform two recursivecomputation steps in a state, then rule r i +1 can perform one computation step.Given a computation with the rule r that takes n recursion steps. Thenthere exists a computation with at most log ( n ) recursive rule applications inthe unfolded program P r,n that results in an equivalent state. We call these optimal rule applications . Proof. The original recursive rule r performs one recursive step when ap-plied. With each unfolding, the number of steps covered by the new unfolded ruleis doubled. For rule r i , i recursive steps are covered.From the condition in the claim it follows that for a query with recursiondepth n , any unfolded rule r i is applicable with n ≥ i . Since the unfolding iscorrect, the resulting states will be equivalent. In one application step of rule r i ,the recursion depth will be reduced to n − i .Then the optimal rule application strategy is to apply rule r i of P r,n suchthat i +1 > n ≥ i . We continue likewise with the resulting recursive goal until n = 0 and we have hit the base case of the recursion. As a consequence of thisstrategy, each of the rules r j with ≤ j ≤ i is applicable at most once becausefrom j +1 > n j ≥ j it follows that j > n j − j ≥ . Since at most log ( n ) rules have been generated by repeated unfolding, the above claim holds. (cid:3) With repeated unfolding up to log ( n ) and optimal rule applications we arereplacing n by log ( n ) recursive calls. For a significant speedup, we also needsimplification. To formalize the speedup, we need the following definition as astarting point. 10 ime Complexity Class n ≥ c ( n ) Recursion r ( n ) Unfolded r ′ ( n )(poly)logarithmic, constant k ≥ log ( n ) k nlog ( n ) k log ( n ) k +1 polynomial, linear k ≥ n k n k +1 n k exponential 2 n n +1 n +1 Figure 1: Speedup in terms of time complexity classes with recursion length n Definition 7 (Worst-Case Runtime Bound) For a given recursive rule r ,let c be a computable unary arithmetic function such that for a given goal with arecursion depth n , c ( n ) is an upper bound on the runtime of the first recursivestep with the original rule r . Note that by this definition, the runtime bound of the next recursive step willbe c ( n − 1) and so on till c (0) which refers to the base case. We will ignore theruntime of base cases since their complexity is usually constant and since theyare not affected by our transformations.A significant speedup can be achieved if we can simplify the built-in con-straints in the unfolded rules so that their runtime does not double with eachunfolding. In the best case, unfolding does not increase the runtime bound ofa recursive step: instead of a time bound of c ( n ) + c ( n ) in the unfolded rule,we still have a bound of c ( n ) with simplified constraints. We call this best-casesimplification . In the following theorem we show how this speedup can changethe complexity class into a lower one. Theorem 2 (Super-Linear Speedup of Repeated Recursion Unfolding) Given an unfolded program P r,n with optimal rule applications. We assumebest-case simplification. Let the function c ( n ) compute a time bound for thefirst recursive step with any recursive rule r i with i ≤ log ( n ) for any querywith recursion depth n . Then the time complexity classes for the original andunfolded recursion are according to Table 1. Proof. Then the runtime for the recursive part of the computation r ( n ) with n ≥ is clearly bounded by nc ( n ) . The time bound can be more preciselymodeled by a recurrence relation of the form r ( n ) = c ( n ) + r ( n − . With optimal rule applications in the unfolded recursion according to Lemma1, the remaining number of recursive steps to be performed is at least halvedgoing from n to n − i : from the condition for optimal rule application i +1 >n ≥ i it follows that i > n/ , n − i < n − n/ and thus n − i < n/ . Wecan therefore model the time bound by the recurrence relation r ′ ( n ) = c ( n ) + r ′ ( n/ . We use constant factors in the complexity classes to emphasize that the actual runtime isexpected to adhere to the constant factor. A recurrence (relation) is an equation that recursively defines a function. A closed-formsolution of a recurrence is a finitary mathematical expression. ow the results in Table 1 can be proven by solving the recurrences. Theycan be verified by inserting the solutions. For upper bounds it suffices to showthat the left hand side is at least as large as the right hand side of the recurrencerelation for n ≥ . For example, let c ( n ) = log ( n ) then r ( n ) = nlog ( n ) = log ( n ) + ( n − log ( n ) ≥ log ( n ) + ( n − log ( n − 1) = c ( n ) + r ( n − and r ′ ( n ) = log ( n ) = log ( n ) + ( log ( n ) − log ( n ) ≥ log ( n ) + ( log ( n ) − = log ( n ) + log ( n/ = c ( n ) + r ′ ( n/ . (cid:3) For linear and polynomial worst-case time complexity classes a super-linearspeedup by the factor O ( n/ 2) is possible, for (poly)logarithmic or constantcomplexity classes a speedup of O ( n/log ( n )), while for exponential complexityclasses no improvement of the complexity class is possible (but the unfoldedrecursion will still run faster). We can readily implement optimal rule applications if we accept some overhead.Besides simply relying on rule order, we present a semi-naive approach in thissection called recursionless recursion. One advantage is that this transformationcompletely eliminates recursion up to a chosen recursion depth. It is thereforewell-suited for hardware synthesis [TORF12]. We transform the recursion away completely based on the observation that in anoptimal rule application, each unfolded recursive rule r i will be applied at mostonce only. We assume that rules are tried in the order in which they appear inthe program as stipulated by the refined semantics of CHR. Definition 8 (Recursionless Recursion) For each i ≤ log ( n ) we replacethe rule r i = H ⇔ C | D, B, R, where R denotes the recursive call in the body, by the pair of rules r i : H i ⇔ C | D, B, R i − r ′ i : H Xi ⇔ R Xi − where for H , H i denotes the recursive constraint H whose constraint symbol c has been renamed to c i , except for H − which is just H , and where H X denotesa user-defined constraint whose arguments are the same sequence of distinctvariables given in X . The same syntax applies to R . omplexity N > n ≥ k ≥ nlog ( n ) k log ( n ) k +1 log ( N ) log ( n ) k +1 log ( N ) log ( n ) k polynomial, linear k ≥ n k +1 n k log ( N ) n k ( log ( N ) + 2) n k exponential 2 n +1 n +1 log ( N )2 n +1 ( log ( N ) + 2)2 n Figure 2: Speedup with worst-case overhead when unfolded up to log ( N )Note that by this construction, each rule is applicable at most once, becausethere is no recursion left. For each recursion level i , relying on rule order, firstrule r i will be tried. It is either applied or otherwise rule r ′ i is applicable. In r ′ i we just pass the argument parameters down to the next lower rule level. So weeither we apply rule r i with no additional overhead or we apply the very simplerule r ′ i which has constant runtime plus the overhead of trying rule r i before. Example 5 (Summation, contd.) The recursionless version of our runningexample is r : sum ( N, S ) ⇔ N > | S := 4 ∗ N − S , sum ( N − , S r ′ : sum ( N, S ) ⇔ sum ( N, S ) r : sum ( N, S ) ⇔ N > | S := 2 ∗ N − S , sum ( N − , S r ′ : sum ( N, S ) ⇔ sum ( N, S ) r : sum ( N, S ) ⇔ N > | S := N + S , sum ( N − , S r ′ : sum ( N, S ) ⇔ sum ( N, S ) sum (1 , S ) ⇔ S = 1 . Rule application attempts that do not lead to rule applications cause an over-head. The overhead depends on the number of unfolded rules and the cost oftrying them. In the best case, the cost for head matching attempts and guardchecking is constant and the resulting overhead is neglectable. For the worstcase we can assume that rule application attempts cost as much time as actualrule applications. This leads to the following lemma. It shows that even in theworst case super-linear speedup is still obtained for most recursion depths. Lemma 2 (Speedup with Worst-Case Overhead) Let N > n . Assumewe have repeatedly unfolded for recursion depth N , i.e. up to log ( N ) . Wehave a query with recursion depth n and complexities c ( n ) , r ( n ) and r ′ ( N ) ascalculated in Theorem 2. Then Table 2 shows the upper bounds on the worst-caseoverhead for the corresponding complexity classes. Proof. When we use rule order alone, up to log ( N ) rules will be tried invain before a rule will be applied. This happens for each recursive call. For thefirst recursive call this incurs a runtime of c ( n ) with each attempt in the worstcase or each application, for the second of c ( n/ and so on. We already know hat the sum of these runtimes is r ′ ( n ) . So instead of the runtime r ′ ( n ) we havea worst-case time bound of log ( N ) r ′ ( n ) . With recursionless recursion we try each rule at most once. With rule orderthe handling of the additional rules r ′ i at each recursion level takes constanttime and we can ignore them in the following. First we try log ( N ) − log ( n ) unfolded rules r i in vain before we reach the rule corresponding to level log ( n ) .From then on, the worst case is the application of all rules below. So overall, log ( N ) − log ( n ) rules are tried once each with runtime c ( n ) and then a runtimeof r ′ ( n ) is incurred, resulting in a bound ( log ( N ) − log ( n )) c ( n ) + r ′ ( n ) . Using these formulas with the complexities for c ( n ) , r ( n ) and r ′ ( N ) from The-orem 2 gives the upper bounds that are listed in somewhat simplified form inTable 2. (cid:3) From Table 2 we can see that the worst case overhead is a factor of O ( log ( N ))for rule order alone. For recursionless recursion, it is a worst case factor of O (2 log ( N ) /log ( n )) for polylogarithmic complexity classes, and a factor of O ( log ( N ) / 2) for polynomial and exponential complexity.In this worst case of recursionless recursion, all complexity classes but ex-ponential complexity are still lower than the complexity classes of the originalrecursions as long as n is larger than log ( N ). Unbounded Recursion. With recursionless recursion, the recursion depthis bounded by N . We can simply eliminate this bound by re-introducing recur-sion for the most unfolded rule r k with k = ⌊ log ( N ) ⌋ : r k = H k ⇔ C | D, B, R k . For N ≤ n we now apply rule r k as long as possible. Of course, recursionlessrecursion is now a misnomer. We have implemented a simple prototype for performing repeated recursionunfolding in CHR and Prolog relying on rule order and recursionless recursion.The source code of the resulting example programs is listed in the appendix. Inour experiments, we used the CHR system in SWI Prolog Version 6.2.1 runningon an Apple Mac mini 2018 with Intel Core i5 8GB RAM and OS-X 10.14.6. Inour benchmarks, unfolding is up to the level given by log ( N ) with N > n . All recursive rules of sum have a constant time for matching the head, check-ing the guard, computing the sum and doing the recursive call including thesubtraction. The recursion depth is determined by the input number n .14 ummation log ( N ) = 25Input n Figure 3: Benchmarks of Summation Super-Linear Speedup. Table 3 lists our benchmark results for repeatedunfolding up to log ( N ) = 25 and input numbers n from 1024 to 8192. Timesare in milliseconds. Summation has been performed once for all numbers in thegiven range. The given timings are the sum of these execution times. The un-folded versions showed constant timings for the number ranges over the completeset of numbers, with recursionless recursion performing about 200 summationsper millisecond. The row Original shows the linear runtime of the given recur-sive summation. Row Rule Order refers to the unfolded recursion of sum relyingon rule order alone, which already shows constant time and at least a ten-foldspeedup. Recursionless refers to the recursionless recursion, it is a factor of fourfaster than the unfolded recursion, again showing constant time. By compari-son, the Prolog implementation of the original rules using the cut operator forefficiency shows again the linear time behavior.According to the Speedup Theorem 2, for the original recursion we expectlinear time complexity O ( n ). According to Lemma 2, for the unfolded pro-gram with rule order the complexity is O ( log ( N ) log ( n )) and with recursion-less recursion O ( log ( N )). Since N is fixed in our benchmarks, this amounts toconstant time.We attribute the better-than-estimated constant time behavior of the un-folded recursion with rule order to the strong variation in rule attempts andapplications with subsequent numbers. For example, while the number 1025requires just one recursive step with rule r , the previous number 1024 needsall smaller recursive steps from r down to r . This behavior leads to constantruntime when we sum over ranges of numbers as in Table 3. This classical program reverses a given list in a naive way. The constraint r ( A, B ) holds if list B is the reversal of list A . We use Prolog notation for lists. r ([ C | A ] , D ) ⇔ r ( A, B ) , a ( B, [ C ] , D ) r ([] , D ) ⇔ D = [] . The built-in constraint a ( X, Y, Z ) appends (concatenates) two lists X and Y into a third list Z . Its runtime is linear in the length of the first list. Repeated Recursion Unfolding. We try to unfold the recursive rule with15 copy of itself: r ([ C | A ] , D ) ⇔ r ( A, B ) , a ( B, [ C ] , D ) r ([ C ′ | A ′ ] , D ′ ) ⇔ r ( A ′ , B ′ ) , a ( B ′ , [ C ′ ] , D ′ ) . However the recursive call in the original rule r ( A, B ) is not an instance of thehead r ([ C ′ | A ′ ] , D ′ ) of the copy of the rule. This is a mere technicality. We move[ C ′ | A ′ ] into the guard and replace it by a new variable A ′′ : r ( A ′′ , D ′ ) ⇔ A ′′ = [ C ′ | A ′ ] | r ( A ′ , B ′ ) , a ( B ′ , [ C ′ ] , D ′ ) . This does not change the semantics of the rule because r ([ C ′ | A ′ ] , D ′ ) ≡ { C ′ ,A ′ ,D ′ } r ( A ′′ , D ′ ) , A ′′ = [ C ′ | A ′ ] . The unfolding is now correct with A ′′ substituted by A in the guard r ([ C | A ] , D ) ⇔ A =[ C ′ | A ′ ] | r ( A, B )= r ( A ′′ , D ′ ) , r ( A ′ , B ′ ) ,a ( B ′ , [ C ′ ] , D ′ ) , a ( B, [ C ] , D ) . Next we use the guard equality A = [ C ′ | A ′ ] to substitute the variable A in thehead r ([ C | A ] , D ) back to [ C ′ | A ′ ]. This is correct since r ([ C | A ] , D ) , A = [ C ′ | A ′ ] ≡ { C,A,D,C ′ ,A ′ } r ([ C, C ′ | A ′ ]] , D ) , A = [ C ′ | A ′ ] . Now we proceed with the simplification for unfolded rules as defined. For thehead and guard we simplify r ([ C, C ′ | A ′ ] , D ) , A = [ C ′ | A ′ ] ≡ { C,D,C ′ ,A ′ } r ([ C, C ′ | A ′ ] , D ) . For the body we simplify A =[ C ′ | A ′ ] , r ( A, B )= r ( A ′′ , D ′ ) , r ( A ′ , B ′ ) , a ( B ′ , [ C ′ ] , D ′ ) , a ( B, [ C ] , D ) ≡ { C,D,C ′ ,A ′ } r ( A ′ , B ′ ) , a ( B ′ , [ C ′ ] , B ) , a ( B, [ C ] , D ) ≡ { C,D,C ′ ,A ′ } r ( A ′ , B ′ ) , a ( B ′ , [ C ′ , C ] , D ) . The eureka moment for best-case simplification is that we can merge the twocalls to constraint a into one if we concatenate their known second arguments.As a result the unfolded rule is simplified into the rule r ([ C, C ′ | A ′ ] , D ) ⇔ r ( A ′ , B ′ ) , a ( B ′ , [ C ′ , C ] , D ) . Repeated recursion unfolding thrice results in the following simplified rules r ([ J, I, H, G, F, E, D, C | A ] , K ) ⇔ r ( A, B ) , a ( B, [ C, D, E, F, G, H, I, J ] , K ) r ([ F, E, D, C | A ] , G ) ⇔ r ( A, B ) , a ( B, [ C, D, E, F ] , G ) r ([ D, C | A ] , E ) ⇔ r ( A, B ) , a ( B, [ C, D ] , E ) r ([ C | A ] , D ) ⇔ r ( A, B ) , a ( B, [ C ] , D ) r ([] , D ) ⇔ D = [] . ist Reversal log ( N ) = 10List Lengths 128-383 384-639 640-895 896-1151 1152-1407 1408-1663 1664-1929Original 496.0 1847.0 4442.0 8630.0 14696.0 23445.0 35487.0Hand-Optimized 7.6 15.4 22.8 30.2 37.4 45.1 52.6Rule Order 5.7 8.0 11.0 12.4 11.8 16.8 22.1Recursionless 3.6 5.8 8.6 9.3 9.1 13.2 17.7Prolog Built-In 4.2 8.6 12.7 16.6 20.9 24.7 29.3 Figure 4: Benchmarks of List ReversalNote that we see here a worst case of program size increase. With each unfolding,the rule size doubles. Still, this does not lead to code explosion since we unfoldonly up to log ( n ) times and therefore the size of all rules added is proportionalto n . Super-Linear Speedup. Repeated recursion unfolding was performed upto log ( N ) = 10. The benchmarks in Table 4 cover all possible list lengths from128 to 1929. Times are in milliseconds. They give the sum of runtimes foreach of the 256 list lengths in the given range of numbers. The row Original stands for the original recursion implementing naive list reversal. Row Hand-Optimized stands for the linear time non-naive list reversal written in CHR.Row Rule Order stands for the repeated unfolding of naive list reversal relyingon rule order alone. Row Recursionless stands for the repeated unfolding ofnaive list reversal were recursion is completely eliminated. Row Prolog Built-In stands for the built-in list reversal of SWI Prolog.According to our Speedup Theorem 2 and Lemma 2, we expect quadraticbehavior for the original recursion and linear behavior for the unfolded recursion,were the recursionless recursion should be twice as fast. This actually holds asthe benchmarks show.All timings show linear time behavior except the original list reversal withoutunfolding. The fastest program version with recursionless recursion reversesabout 100 list elements per millisecond. The transformed code executed twiceas fast as the hand-coded well-known linear version of list reversal that doesnot use list concatenation. Surprisingly, our recursionless recursion proved evenfaster than the built-in optimized reverse/2 of SWI Prolog.Note that the runtimes around 1024 almost stay constant. Our most un-folded rule with i = N = 10 handles a list with 2 = 1024 elements. Againwe attribute this averaging effect of considering ranges of inputs. For example,a list of length 1024 needs one rule application with rule r at recursion level i = 10 before the base case is reached, while with 1023 we need to apply allrules for each level i < 10. 17 Related Work Program transformation to improve efficiency is usually concerned with a strat-egy for the combination of unfolding and folding techniques to replace codestarting with [BD77]. In the literature, recursion is usually unfolded severaltimes together with the base case and then simplified. We rely solely on unfold-ing the recursive part and repeat the process. We ignore the base case. We addredundant rules this way but never remove any.Program transformation as a tool for specific aims and applications is abun-dant in CHR, for an overview see [SVWSDK10, Fr¨u15]. General methods forunfolding [GMTW15] exist (which we have used in this paper), for specializingrules with regard to a specific given query [Fr¨u05], and for optimization inducedby confluence [AF04].In [Amt91] unfolding-based meta-level systems for Prolog consist of a hierar-chy of additional meta-rules and a hierarchical execution scheme, i.e. a changein semantics. These rules are described as shortcuts obtained from unfold/foldoperations. Presumably, when adapted to Prolog, the rules generated by re-peated recursion unfolding could be considered as meta-rules in this genericframework.Directly related literature is sparse. One reason could be that our approach isbased on generating and keeping redundant rules which seems counter-intuitiveat first. Moreover, super-linear speedups are a rare feat and mostly concernparallel programs, while our approach applies to sequential programs. An ex-ception is work based on supercompilation. In this program transformation,generalisation while unfolding increases the chance for folding. Using advancedgeneralisation techniques for supercompilation, distillation [Ham09] and equal-ity indices [GKN16] can achieve super-linear speedup on some examples. Incontrast, our approach is straightforward, as it does not involve generalisationor folding, and is applied to a programming language in practical use. Repeated recursion unfolding is a new approach that repeatedly unfolds a re-cursion with itself and simplifies it while keeping all unfolded rules. We provedits correctness.We showed there exists an optimal rule application strategy such that signif-icant speedups are possible. We proved a super-linear speedup theorem in caseof best-case simplification. Then our program transformation lowers the timecomplexity of a recursion for polylogarithmic classes by a factor of O ( n/log ( n ))and for polynomial classes by a factor of O ( n ).For a semi-naive implementation of repeated recursion unfolding, recursion-less recursion, we proved an overhead which is linear in the number of unfoldedrules. Super-linear speedup is still obtained in most cases. The actual runtimeimprovement quickly reaches several orders of magnitude. Our approach im-proves the time complexity from linear to constant for the summation example18nd from quadratic to linear for list reversal. The latter runs faster than abuilt-in hand-optimized version.While our speedups are super-linear, it is too early to tell which recursivealgorithms allow for the necessary best-case simplification. A good simplificationrequires some insight and thus in general cannot be found automatically.We defined and implemented repeated recursion unfolding using the rule-based language CHR (Constraint Handling Rules), but we think our approachcan be applied to mainstream programming languages and hardware synthesisas well. Ongoing and future work. To extend our approach to mutual recursionas well as multiple recursive rules should be straightforward. Indeed, we al-ready could derive a novel double recursive linear-time algorithm from a naiveexponential-time double recursion for Fibonacci numbers.In this paper, the super-linear speedup is bounded in the sense that it holdsup to a chosen upper bound on the number of recursive steps. In ongoing work,we have succeeded for the examples in this paper to extend our approach torun-time dynamic on-the-fly just-in-time repeated recursion unfolding so thatthe super-linear speedup is unbounded, i.e. independent of the recursion depth.The implementation overhead of optimal rule applications can be reducedwith indexing on the recursion depth. We already have implemented indexingfor the examples in this paper.One could also transfer our approach from recursion to loop constructs inother programming languages. We have already done examples for Java. Acknowledgements. Part of this research work was performed during thesabbatical of the author in summer semester 2020. We thank the anonymousreviewers for their skepticism which helped to clarify the contribution of thepaper. References [AF04] Slim Abdennadher and Thom Fr¨uhwirth. Integration and opti-mization of rule-based constraint solvers. In M. Bruynooghe,editor, LOPSTR ’03 , volume 3018 of LNCS , pages 198–213.Springer, 2004.[Amt91] Torben Amtoft. Properties of unfolding-based meta-level sys-tems. In Proceedings of the 1991 ACM SIGPLAN Symposium onPartial Evaluation and Semantics-based Program Manipulation ,PEPM ’91, pages 243–254, New York, NY, USA, 1991. ACM.[BD77] Rod M Burstall and John Darlington. A transformation systemfor developing recursive programs. Journal of the ACM (JACM) ,24(1):44–67, 1977.[Bet14] Hariolf Betz. A unified analytical foundation for constraint han-dling rules . BoD, 2014.19DSGH04] Gregory J. Duck, Peter J. Stuckey, Mar´ıa Garc´ıa de la Banda,and Christian Holzbaur. The refined operational semantics ofConstraint Handling Rules. In B. Demoen and V. Lifschitz, ed-itors, ICLP ’04 , volume 3132 of LNCS , pages 90–104. Springer,September 2004.[Fr¨u05] Thom Fr¨uhwirth. Specialization of concurrent guarded multi-settransformation rules. In S. Etalle, editor, LOPSTR ’04 , volume3573 of LNCS , pages 133–148. Springer, 2005.[Fr¨u09] Thom Fr¨uhwirth. Constraint Handling Rules (Monography) .Cambridge University Press, August 2009.[Fr¨u15] Thom Fr¨uhwirth. Constraint handling rules - what else? In RuleTechnologies: Foundations, Tools, and Applications - 9th Inter-national Symposium, RuleML 2015, Berlin, Germany, August2-5, 2015, Proceedings , pages 13–34, 2015.[GKN16] Robert Gl¨uck, Andrei Klimov, and Antonina Nepeivoda. Nonlin-ear configurations for superlinear speedup by supercompilation.In Fifth International Valentin Turchin Workshop on Metacom-putation , page 32. University of Pereslavl, 2016.[GMTW15] Maurizio Gabbrielli, Maria Chiara Meo, Paolo Tacchella, andHerbert Wiklicky. Unfolding for chr programs. Theory and Prac-tice of Logic Programming , 15(3):264–311, 2015.[Ham09] Geoff W Hamilton. Extracting the essence of distillation. In In-ternational Andrei Ershov Memorial Conference on Perspectivesof System Informatics , pages 151–164. Springer, 2009.[RBF09] Frank Raiser, Hariolf Betz, and Thom Fr¨uhwirth. Equivalenceof CHR states revisited. In F. Raiser and J. Sneyers, editors, CHR ’09 , pages 33–48. K.U.Leuven, Dept. Comp. Sc., Technicalreport CW 555, July 2009.[SVWSDK10] Jon Sneyers, Peter Van Weert, Tom Schrijvers, and LeslieDe Koninck. As time goes by: Constraint Handling Rules – Asurvey of CHR research between 1998 and 2007. TPLP , 10(1):1–47, 2010.[TORF12] Andrea Triossi, Salvatore Orlando, Alessandra Raffaet`a, andThom Fr¨uhwirth. Compiling CHR to parallel hardware. In Prin-ciples and Practice of Declarative Programming, PPDP’12, Leu-ven, Belgium - September 19 - 21, 2012 , pages 173–184, 2012.20 Proof of Correctness of Rule Simplification For correctness of rule simplification (see Subsection 3.2) we have to show thatthe same transitions S T are possible with rule r and rule simplify ( r ). Hereis the full proof for Theorem 1. Theorem 1 (Correctness of Rule Simplification) Let r = ( H ⇔ C | D ∧ B ) be a rule and let s = ( H ′ ⇔ C ′ | D ′ \ C ′ ∧ B ′ ) be the simplified rule simplify ( r ) .For any state S and variables V , S r T iff S s T . Proof. According to the definition of a CHR transition and simplify ( r ) , weknow that S r T iff S ≡ V ( H ∧ C ∧ G ) false and ( C ∧ D ∧ B ∧ G ) ≡ V TS s T iff S ≡ V ( H ′ ∧ C ′ ∧ G ′ ) false and ( C ′ ∧ D ′ \ C ′ ∧ B ′ ∧ G ′ ) ≡ V T ( H ∧ C ) ≡ V ′ ( H ′ ∧ C ′ )( C ∧ D ∧ B ) ≡ V ′ ( D ′ ∧ B ′ ) . It suffices to show that S r T implies S s T , since the implication in theother direction is symmetric and can be shown in the same way. Hence we haveto show that there exists a goal G ′ such that S ≡ ( H ∧ C ∧ G ) ≡ V ( H ′ ∧ C ′ ∧ G ′ ) if ( H ∧ C ) ≡ V ′ ( H ′ ∧ C ′ ) and T ≡ ( C ∧ D ∧ B ∧ G ) ≡ V ( C ′ ∧ D ′ \ C ′ ∧ B ′ ∧ G ′ ) if ( C ∧ D ∧ B ) ≡ V ′ ( D ′ ∧ B ′ ) . To show the first part concerning state S , we proceed as follows. We choose G ′ = C ∧ G . Let G = ( G C ∧ G B ) where G C are the built-in constraints and G B are the user-defined constraints of G . According to the definition of stateequivalence and its transitivity we have to show that the two states equivalent to S are equivalent CT | = ∀ ( C ∧ G C → ∃ ¯ y (( H ∧ G B ) = ( H ′ ∧ G B ) ∧ C ′ ∧ C ∧ G C )) ∧ ∀ ( C ′ ∧ C ∧ G C → ∃ ¯ x (( H ∧ G B ) = ( H ′ ∧ G B ) ∧ C ∧ G C )) if CT | = ∀ ( C → ∃ ¯ y ′ (( H = H ′ ) ∧ C ′ )) ∧ ∀ ( C ′ → ∃ ¯ x ′ (( H = H ′ ) ∧ C )) , where the ¯ x ′ , ¯ y ′ , ¯ x, ¯ y are local variables, such that • ¯ x ′ are the variables in H ∧ C only that are not in V ′ , • ¯ y ′ are the variables in H ′ ∧ C ′ only that are not in V ′ , • ¯ x are the variables in H ∧ C ∧ G that are not in V , • ¯ y are the variables in H ′ ∧ C ′ ∧ G ′ that are not in V .By the definition of simplification, V ′ are the variables in H and H ′ . By defini-tion of the transition, ¯ x includes the local variables of the given rule, i.e. thosenot in the head H , and ¯ y includes the local variables of the simplified rule, i.e.those not in the head H ′ . rom these facts we can conclude that ¯ x includes the variables of ¯ x ′ and that ¯ y includes the variables of ¯ y ′ . The remaining variables in ¯ x are those in G thatare not in V , the remaining variables in ¯ y are those in G ′ that are not in V .Since G ′ = C ∧ G , ¯ y includes the variables of ¯ x in addition those in C ′ that arenot in H ′ . We can therefore write ¯ x as ¯ x ′ ¯ z and ¯ y as ¯ y ′ ¯ z ¯ w .Now consider the precondition CT | = ∀ ( C → ∃ ¯ y ′ (( H = H ′ ) ∧ C ′ )) ∧ ∀ ( C ′ → ∃ ¯ x ′ (( H = H ′ ) ∧ C )) , We can always add existential quantifiers to the conclusion of an implication,since A → B implies A → ∃ ¯ vB in first-order predicate logic. CT | = ∀ ( C → ∃ ¯ y ′ ¯ z ¯ w (( H = H ′ ) ∧ C ′ )) ∧ ∀ ( C ′ → ∃ ¯ x ′ ¯ z (( H = H ′ ) ∧ C )) . Since CT | = G B = G B we can extend H = H ′ to ( H ∧ G B ) = ( H ′ ∧ G B ) andsince A → ∃ ¯ vA for all A and ¯ v we can extend the implications on both sides by G C and C ∧ G C , respectively. Since ¯ x = ¯ x ′ ¯ z and ¯ y = ¯ y ′ ¯ z ¯ w , we finally arrive at CT | = ∀ ( C ∧ G C → ∃ ¯ y (( H ∧ G B ) = ( H ′ ∧ G B ) ∧ C ′ ∧ C ∧ G C )) ∧ ∀ ( C ′ ∧ C ∧ G C → ∃ ¯ x (( H ∧ G B ) = ( H ′ ∧ G B ) ∧ C ∧ G C )) . In the same manner we can show that the two states equivalent to state T are equivalent by observing that the local variables of C, D, B and C ′ , D ′ , B ′ are the local variables of the respective rules and are thus also included in thelocal variables of the two states equivalent to T . Also note that ( C ′ ∧ D ′ \ C ′ ) =( C ′ ∧ D ′ ) . (cid:3) B Program Code Listings B.1 Summation, unfolded up to N= sum25(A,C) <=> A>33554432 | B is A-33554432, sum24(B, D),C is 33554432*A-562949936644096+D.sum25(A,B) <=> sum24(A,B).sum24(A,C) <=> A>16777216 | B is A-16777216, sum23(B, D),C is 16777216*A-140737479966720+D.sum24(A,B) <=> sum23(A,B).sum23(A,C) <=> A>8388608 | B is A-8388608, sum22(B, D),C is 8388608*A-35184367894528+D.sum23(A,B) <=> sum22(A,B).sum22(A,C) <=> A>4194304 | B is A-4194304, sum21(B, D),C is 4194304*A-8796090925056+D.sum22(A,B) <=> sum21(A,B).sum21(A,C) <=> A>2097152 | B is A-2097152, sum20(B, D),C is 2097152*A-2199022206976+D.sum21(A,B) <=> sum20(A,B).sum20(A,C) <=> A>1048576 | B is A-1048576, sum19(B, D), is 1048576*A-549755289600+D.sum20(A,B) <=> sum19(A,B).sum19(A,C) <=> A>524288 | B is A-524288, sum18(B, D),C is 524288*A-137438691328+D.sum19(A,B) <=> sum18(A,B).sum18(A,C) <=> A>262144 | B is A-262144, sum17(B, D),C is 262144*A-34359607296+D.sum18(A,B) <=> sum17(A,B).sum17(A,C) <=> A>131072 | B is A-131072, sum16(B, D),C is 131072*A-8589869056+D.sum17(A,B) <=> sum16(A,B).sum16(A,C) <=> A>65536 | B is A-65536, sum15(B, D),C is 65536*A-2147450880+D.sum16(A,B) <=> sum15(A,B).sum15(A,C) <=> A>32768 | B is A-32768, sum14(B, D),C is 32768*A-536854528+D.sum15(A,B) <=> sum14(A,B).sum14(A,C) <=> A>16384 | B is A-16384, sum13(B, D),C is 16384*A-134209536+D.sum14(A,B) <=> sum13(A,B).sum13(A,C) <=> A>8192 | B is A-8192, sum12(B, D), C is 8192*A-33550336+D.sum13(A,B) <=> sum12(A,B).sum12(A,C) <=> A>4096 | B is A-4096, sum11(B, D), C is 4096*A-8386560+D.sum12(A,B) <=> sum11(A,B).sum11(A,C) <=> A>2048 | B is A-2048, sum10(B, D), C is 2048*A-2096128+D.sum11(A,B) <=> sum10(A,B).sum10(A,C) <=> A>1024 | B is A-1024, sum9(B, D), C is 1024*A-523776+D.sum10(A,B) <=> sum9(A,B).sum9(A,C) <=> A>512 | B is A-512, sum8(B, D), C is 512*A-130816+D.sum9(A,B) <=> sum8(A,B).sum8(A,C) <=> A>256 | B is A-256, sum7(B, D), C is 256*A-32640+D.sum8(A,B) <=> sum7(A,B).sum7(A,C) <=> A>128 | B is A-128, sum6(B, D), C is 128*A-8128+D.sum7(A,B) <=> sum6(A,B).sum6(A,C) <=> A>64 | B is A-64, sum5(B, D), C is 64*A-2016+D.sum6(A,B) <=> sum5(A,B).sum5(A,C) <=> A>32 | B is A-32, sum4(B, D), C is 32*A-496+D.sum5(A,B) <=> sum4(A,B).sum4(A,C) <=> A>16 | B is A-16, sum3(B, D), C is 16*A-120+D.sum4(A,B) <=> sum3(A,B).sum3(A,C) <=> A>8 | B is A-8, sum2(B, D), C is 8*A-28+D.sum3(A,B) <=> sum2(A,B).sum2(A,C) <=> A>4 | B is A-4, sum1(B, D), C is 4*A-6+D.sum2(A,B) <=> sum1(A,B).sum1(A,C) <=> A>2 | B is A-2, sum0(B, D), C is 2*A-1+D.sum1(A,B) <=> sum0(A,B).sum0(A,C) <=> A>1 | B is A-1, sum(B, D), C is A+D.sum0(A,B) <=> sum(A,B).sum(1, A) <=> A=1. .2 List Reversal, unfolded up to N= r10([L39,K39,J39,I39,H39,G39,F39,E39,D39,C39,B39,A39,Z38,Y38,X38,W38,V38,U38,T38,S38,R38,Q38,P38,O38,N38,M38,L38,K38,J38,I38,H38,G38,F38,E38,D38,C38,B38,A38,Z37,Y37,X37,W37,V37,U37,T37,S37,R37,Q37,P37,O37,N37,M37,L37,K37,J37,I37,H37,G37,F37,E37,D37,C37,B37,A37,Z36,Y36,X36,W36,V36,U36,T36,S36,R36,Q36,P36,O36,N36,M36,L36,K36,J36,I36,H36,G36,F36,E36,D36,C36,B36,A36,Z35,Y35,X35,W35,V35,U35,T35,S35,R35,Q35,P35,O35,N35,M35,L35,K35,J35,I35,H35,G35,F35,E35,D35,C35,B35,A35,Z34,Y34,X34,W34,V34,U34,T34,S34,R34,Q34,P34,O34,N34,M34,L34,K34,J34,I34,H34,G34,F34,E34,D34,C34,B34,A34,Z33,Y33,X33,W33,V33,U33,T33,S33,R33,Q33,P33,O33,N33,M33,L33,K33,J33,I33,H33,G33,F33,E33,D33,C33,B33,A33,Z32,Y32,X32,W32,V32,U32,T32,S32,R32,Q32,P32,O32,N32,M32,L32,K32,J32,I32,H32,G32,F32,E32,D32,C32,B32,A32,Z31,Y31,X31,W31,V31,U31,T31,S31,R31,Q31,P31,O31,N31,M31,L31,K31,J31,I31,H31,G31,F31,E31,D31,C31,B31,A31,Z30,Y30,X30,W30,V30,U30,T30,S30,R30,Q30,P30,O30,N30,M30,L30,K30,J30,I30,H30,G30,F30,E30,D30,C30,B30,A30,Z29,Y29,X29,W29,V29,U29,T29,S29,R29,Q29,P29,O29,N29,M29,L29,K29,J29,I29,H29,G29,F29,E29,D29,C29,B29,A29,Z28,Y28,X28,W28,V28,U28,T28,S28,R28,Q28,P28,O28,N28,M28,L28,K28,J28,I28,H28,G28,F28,E28,D28,C28,B28,A28,Z27,Y27,X27,W27,V27,U27,T27,S27,R27,Q27,P27,O27,N27,M27,L27,K27,J27,I27,H27,G27,F27,E27,D27,C27,B27,A27,Z26,Y26,X26,W26,V26,U26,T26,S26,R26,Q26,P26,O26,N26,M26,L26,K26,J26,I26,H26,G26,F26,E26,D26,C26,B26,A26,Z25,Y25,X25,W25,V25,U25,T25,S25,R25,Q25,P25,O25,N25,M25,L25,K25,J25,I25,H25,G25,F25,E25,D25,C25,B25,A25,Z24,Y24,X24,W24,V24,U24,T24,S24,R24,Q24,P24,O24,N24,M24,L24,K24,J24,I24,H24,G24,F24,E24,D24,C24,B24,A24,Z23,Y23,X23,W23,V23,U23,T23,S23,R23,Q23,P23,O23,N23,M23,L23,K23,J23,I23,H23,G23,F23,E23,D23,C23,B23,A23,Z22,Y22,X22,W22,V22,U22,T22,S22,R22,Q22,P22,O22,N22,M22,L22,K22,J22,I22,H22,G22,F22,E22,D22,C22,B22,A22,Z21,Y21,X21,W21,V21,U21,T21,S21,R21,Q21,P21,O21,N21,M21,L21,K21,J21,I21,H21,G21,F21,E21,D21,C21,B21,A21,Z20,Y20,X20,W20,V20,U20,T20,S20,R20,Q20,P20,O20,N20,M20,L20,K20,J20,I20,H20,G20,F20,E20,D20,C20,B20,A20,Z19,Y19,X19,W19,V19,U19,T19,S19,R19,Q19,P19,O19,N19,M19,L19,K19,J19,I19,H19,G19,F19,E19,D19,C19,B19,A19,Z18,Y18,X18,W18,V18,U18,T18,S18,R18,Q18,P18,O18,N18,M18,L18,K18,J18,I18,H18,G18,F18,E18,D18,C18,B18,A18,Z17,Y17,X17,W17,V17,U17,T17,S17,R17,Q17,P17,O17,N17,M17,L17,K17,J17,I17,H17,G17,F17,E17,D17,C17,B17,A17,Z16,Y16,X16,W16,V16,U16,T16,S16,R16,Q16,P16,O16,N16,M16,L16,K16,J16,I16,H16,G16,F16,E16,D16,C16,B16,A16,Z15,Y15,X15,W15,V15,U15,T15,S15,R15,Q15,P15,O15,N15,M15,L15,K15,J15,I15,H15,G15,F15,E15,D15,C15,B15,A15,Z14,Y14,X14,W14,V14,U14,T14,S14,R14,Q14,P14,O14,N14,M14,L14,K14,J14,I14,H14,G14,F14,E14,D14,C14,B14,A14,Z13,Y13,X13,W13,V13,U13,T13,S13,R13,Q13,P13,O13,N13,M13,L13,K13,J13,I13,H13,G13,F13,E13,D13,C13,B13,A13,Z12,Y12,X12,W12,V12,U12,T12,S12,R12,Q12,P12,O12,N12,M12,L12,K12,J12,I12,H12,G12,F12,E12,D12,C12,B12,A12,Z11,Y11,X11,W11,V11,U11,T11,S11,R11,Q11,P11,O11,N11,M11,L11,K11,J11,I11,H11,G11,F11,E11,D11,C11,B11,A11,Z10,Y10,X10,W10,V10,U10,T10,S10,R10,Q10,P10,O10,N10,M10,L10,K10,J10,I10,H10,G10,F10,E10,D10,C10,B10,A10,Z9,Y9,X9,W9,V9,U9,T9,S9,R9,Q9,P9,O9,N9,M9,L9,K9,J9,I9,H9,G9,F9,E9,D9,C9,B9,A9,Z8,Y8,X8,W8,V8,U8,T8,S8,R8,Q8,P8,O8,N8,M8,L8,K8,J8,I8,H8,G8,F8,E8,D8,C8,B8,A8,Z7,Y7,X7,W7,V7,U7,T7,S7,R7,Q7,P7,O7,N7,M7,L7,K7,J7,I7,H7,G7,F7,E7,D7,C7,B7,A7,Z6,Y6,X6,W6,V6,U6,T6,S6,R6,Q6,P6,O6,N6,M6,L6,K6,J6,I6,H6,G6,F6,E6,D6,C6,B6,A6,Z5,Y5,X5,W5,V5,U5,T5,S5,R5,Q5,P5,O5,N5,M5,L5,K5,J5,I5,H5,G5,F5,E5,D5,C5,B5,A5,Z4,Y4,X4,W4,V4,U4,T4,S4,R4,Q4,P4,O4,N4,M4,L4,K4,J4,I4,H4,G4,F4,E4,D4,C4,B4,A4,Z3,Y3,X3,W3,V3,U3,T3,S3,R3,Q3,P3,O3,N3,M3,L3,K3,J3,I3,H3,G3,F3,E3,D3,C3,B3,A3,Z2,Y2,X2,W2,V2,U2,T2,S2,R2,Q2,P2,O2,N2,M2,L2,K2,J2,I2,H2,G2,F2,E2,D2,C2,B2,A2,Z1,Y1,X1,W1,V1,U1,T1,S1,R1,Q1,P1,O1,N1,M1,L1,K1,J1,I1,H1,G1,F1,E1,D1,C1,B1,A1,Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C|A],M39) <=> r9(A,B),append(B,[C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2,N2,O2,P2,Q2,R2,S2,T2,U2,V2,W2,X2,Y2,Z2,A3,B3,C3,D3,E3,F3,G3,H3,I3,J3,K3,L3,M3,N3,O3,P3,Q3,R3,S3,T3,U3,V3,W3,X3,Y3,Z3,A4,B4,C4,D4,E4,F4,G4,H4,I4,J4,K4,L4,M4,N4,O4,P4,Q4,R4,S4,T4,U4,V4,W4,X4,Y4,Z4,A5,B5,C5,D5,E5,F5,G5,H5,I5,J5,K5,L5,M5,N5,O5,P5,Q5,R5,S5,T5,U5,V5,W5,X5,Y5,Z5,A6,B6,C6,D6,E6,F6,G6,H6,I6,J6,K6,L6,M6,N6,O6,P6,Q6,R6,S6,T6,U6,V6,W6,X6,Y6,Z6,A7,B7,C7,D7,E7,F7,G7,H7,I7,J7,K7,L7,M7,N7,O7,P7,Q7,R7,S7,T7,U7,V7,W7,X7,Y7,Z7,A8,B8,C8,D8,E8,F8,G8,H8,I8,J8,K8,L8,M8,N8,O8,P8,Q8,R8,S8,T8,U8,V8,W8,X8,Y8,Z8,A9,B9,C9,D9,E9,F9,G9,H9,I9,J9,K9,L9,M9,N9,O9,P9,Q9,R9,S9,T9,U9,V9,W9,X9,Y9,Z9,A10,B10,C10,D10,E10,F10,G10,H10,I10,J10,K10,L10,M10,N10,O10,P10,Q10,R10,S10,T10,U10,V10,W10,X10,Y10,Z10,A11,B11,C11,D11,E11,F11,G11,H11,I11,J11,K11,L11,M11,N11,O11,P11,Q11,R11,S11,T11,U11,V11,W11,X11,Y11,Z11,A12,B12,C12,D12,E12,F12,G12,H12,I12,J12,K12,L12,M12,N12,O12,P12,Q12,R12,S12,T12,U12,V12,W12,X12,Y12,Z12,A13,B13,C13,D13,E13,F13,G13,H13,I13,J13,K13,L13,M13,N13,O13,P13,Q13,R13,S13,T13,U13,V13,W13,X13,Y13,Z13,A14,B14,C14,D14,E14,F14,G14,H14,I14,J14,K14,L14,M14,N14,O14,P14,Q14,R14,S14,T14,U14,V14,W14,X14,Y14,Z14,A15,B15,C15,D15,E15,F15,G15,H15,I15,J15,K15,L15,M15,N15,O15,P15,Q15,R15,S15,T15,U15,V15,W15,X15,Y15,Z15,A16,B16,C16,D16,E16,F16,G16,H16,I16,J16,K16,L16,M16,N16,O16,P16,Q16,R16,S16,T16,U16,V16,W16,X16,Y16,Z16,A17,B17,C17,D17,E17,F17,G17,H17,I17,J17,K17,L17,M17,N17,O17,P17,Q17,R17,S17,T17,U17,V17,W17,X17,Y17,Z17,A18,B18,C18,D18,E18,F18,G18,H18,I18,J18,K18,L18,M18,N18,O18,P18,Q18,R18,S18,T18,U18,V18,W18,X18,Y18,Z18,A19,B19,C19,D19,E19,F19,G19,H19,I19,J19,K19,L19,M19,N19,O19,P19,Q19,R19,S19,T19,U19,V19,W19,X19,Y19,Z19,A20,B20,C20,D20,E20,F20,G20,H20,I20,J20,K20,L20,M20,N20,O20,P20,Q20,R20,S20,T20,U20,V20,W20,X20,Y20,Z20,A21,B21,C21,D21,E21,F21,G21,H21,I21,J21,K21,L21,M21,N21,O21,P21,Q21,R21,S21,T21,U21,V21,W21,X21,Y21,Z21,A22,B22,C22,D22,E22,F22,G22,H22,I22,J22,K22,L22,M22,N22,O22,P22,Q22,R22,S22,T22,U22,V22,W22,X22,Y22,Z22,A23,B23,C23,D23,E23,F23,G23,H23,I23,J23,K23,L23,M23,N23,O23,P23,Q23,R23,S23,T23,U23,V23,W23,X23,Y23,Z23,A24,B24,C24,D24,E24,F24,G24,H24,I24,J24,K24,L24,M24,N24,O24,P24,Q24,R24,S24,T24,U24,V24,W24,X24,Y24,Z24,A25,B25,C25,D25,E25,F25,G25,H25,I25,J25,K25,L25,M25,N25,O25,P25,Q25,R25,S25,T25,U25,V25,W25,X25,Y25,Z25,A26,B26,C26,D26,E26,F26,G26,H26,I26,J26,K26,L26,M26,N26,O26,P26,Q26,R26,S26,T26,U26,V26,W26,X26,Y26,Z26,A27,B27,C27,D27,E27,F27,G27,H27,I27,J27,K27,L27,M27,N27,O27,P27,Q27,R27,S27,T27,U27,V27,W27,X27,Y27,Z27,A28,B28,C28,D28,E28,F28,G28,H28,I28,J28,K28,L28,M28,N28,O28,P28,Q28,R28,S28,T28,U28,V28,W28,X28,Y28,Z28,A29,B29,C29,D29,E29,F29,G29,H29,I29,J29,K29,L29,M29,N29,O29,P29,Q29,R29,S29,T29,U29,V29,W29,X29,Y29,Z29,A30,B30,C30,D30,E30,F30,G30,H30,I30,J30,K30,L30,M30,N30,O30,P30,Q30,R30,S30,T30,U30,V30,W30,X30,Y30,Z30,A31,B31,C31,D31,E31,F31,G31,H31,I31,J31,K31,L31,M31,N31,O31,P31,Q31,R31,S31,T31,U31,V31,W31,X31,Y31,Z31,A32,B32,C32,D32,E32,F32,G32,H32,I32,J32,K32,L32,M32,N32,O32,P32,Q32,R32,S32,T32,U32,V32,W32,X32,Y32,Z32,A33,B33,C33,D33,E33,F33,G33,H33,I33,J33,K33,L33,M33,N33,O33,P33,Q33,R33,S33,T33,U33,V33,W33,X33,Y33,Z33,A34,B34,C34,D34,E34,F34,G34,H34,I34,J34,K34,L34,M34,N34,O34,P34,Q34,R34,S34,T34,U34,V34,W34,X34,Y34,Z34,A35,B35,C35,D35,E35,F35,G35,H35,I35,J35,K35,L35,M35,N35,O35,P35,Q35,R35,S35,T35,U35,V35,W35,X35,Y35,Z35,A36,B36,C36,D36,E36,F36,G36,H36,I36,J36,K36,L36,M36,N36,O36,P36,Q36,R36,S36,T36,U36,V36,W36,X36,Y36,Z36,A37,B37,C37,D37,E37,F37,G37,H37,I37,J37,K37,L37,M37,N37,O37,P37,Q37,R37,S37,T37,U37,V37,W37,X37,Y37,Z37,A38,B38,C38,D38,E38,F38,G38,H38,I38,J38,K38,L38,M38,N38,O38,P38,Q38,R38,S38,T38,U38,V38,W38,X38,Y38,Z38,A39,B39,C39,D39,E39,F39,G39,H39,I39,J39,K39,L39],M39).r10(A,B) <=> r9(A,B).r9([T19,S19,R19,Q19,P19,O19,N19,M19,L19,K19,J19,I19,H19,G19,F19,E19,D19,C19,B19,A19,Z18,Y18,X18,W18,V18,U18,T18,S18,R18,Q18,P18,O18,N18,M18,L18,K18,J18,I18,H18,G18,F18,E18,D18,C18,B18,A18,Z17,Y17,X17,W17,V17,U17,T17,S17,R17,Q17,P17,O17,N17,M17,L17,K17,J17,I17,H17,G17,F17,E17,D17,C17,B17,A17,Z16,Y16,X16,W16,V16,U16,T16,S16,R16,Q16,P16,O16,N16,M16,L16,K16,J16,I16,H16,G16,F16,E16,D16,C16,B16,A16,Z15,Y15,X15,W15,V15,U15,T15,S15,R15,Q15,P15,O15,N15,M15,L15,K15,J15,I15,H15,G15,F15,E15,D15,C15,B15,A15,Z14,Y14,X14,W14,V14,U14,T14,S14,R14,Q14,P14,O14,N14,M14,L14,K14,J14,I14,H14,G14,F14,E14,D14,C14,B14,A14,Z13,Y13,X13,W13,V13,U13,T13,S13,R13,Q13,P13,O13,N13,M13,L13,K13,J13,I13,H13,G13,F13,E13,D13,C13,B13,A13,Z12,Y12,X12,W12,V12,U12,T12,S12,R12,Q12,P12,O12,N12,M12,L12,K12,J12,I12,H12,G12,F12,E12,D12,C12,B12,A12,Z11,Y11,X11,W11,V11,U11,T11,S11,R11,Q11,P11,O11,N11,M11,L11,K11,J11,I11,H11,G11,F11,E11,D11,C11,B11,A11,Z10,Y10,X10,W10,V10,U10,T10,S10,R10,Q10,P10,O10,N10,M10,L10,K10,J10,I10,H10,G10,F10,E10,D10,C10,B10,A10,Z9,Y9,X9,W9,V9,U9,T9,S9,R9,Q9,P9,O9,N9,M9,L9,K9,J9,I9,H9,G9,F9,E9,D9,C9,B9,A9,Z8,Y8,X8,W8,V8,U8,T8,S8,R8,Q8,P8,O8,N8,M8,L8,K8,J8,I8,H8,G8,F8,E8,D8,C8,B8,A8,Z7,Y7,X7,W7,V7,U7,T7,S7,R7,Q7,P7,O7,N7,M7,L7,K7,J7,I7,H7,G7,F7,E7,D7,C7,B7,A7,Z6,Y6,X6,W6,V6,U6,T6,S6,R6,Q6,P6,O6,N6,M6,L6,K6,J6,I6,H6,G6,F6,E6,D6,C6,B6,A6,Z5,Y5,X5,W5,V5,U5,T5,S5,R5,Q5,P5,O5,N5,M5,L5,K5,J5,I5,H5,G5,F5,E5,D5,C5,B5,A5,Z4,Y4,X4,W4,V4,U4,T4,S4,R4,Q4,P4,O4,N4,M4,L4,K4,J4,I4,H4,G4,F4,E4,D4,C4,B4,A4,Z3,Y3,X3,W3,V3,U3,T3,S3,R3,Q3,P3,O3,N3,M3,L3,K3,J3,I3,H3,G3,F3,E3,D3,C3,B3,A3,Z2,Y2,X2,W2,V2,U2,T2,S2,R2,Q2,P2,O2,N2,M2,L2,K2,J2,I2,H2,G2,F2,E2,D2,C2,B2,A2,Z1,Y1,X1,W1,V1,U1,T1,S1,R1,Q1,P1,O1,N1,M1,L1,K1,J1,I1,H1,G1,F1,E1,D1,C1,B1,A1,Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C|A],U19) <=> r8(A,B),append(B,[C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2,N2,O2,P2,Q2,R2,S2,T2,U2,V2,W2,X2,Y2,Z2,A3,B3,C3,D3,E3,F3,G3,H3,I3,J3,K3,L3,M3,N3,O3,P3,Q3,R3,S3,T3,U3,V3,W3,X3,Y3,Z3,A4,B4,C4,D4,E4,F4,G4,H4,I4,J4,K4,L4,M4,N4,O4,P4,Q4,R4,S4,T4,U4,V4,W4,X4,Y4,Z4,A5,B5,C5,D5,E5,F5,G5,H5,I5,J5,K5,L5,M5,N5,O5,P5,Q5,R5,S5,T5,U5,V5,W5,X5,Y5,Z5,A6,B6,C6,D6,E6,F6,G6,H6,I6,J6,K6,L6,M6,N6,O6,P6,Q6,R6,S6,T6,U6,V6,W6,X6,Y6,Z6,A7,B7,C7,D7,E7,F7,G7,H7,I7,J7,K7,L7,M7,N7,O7,P7,Q7,R7,S7,T7,U7,V7,W7,X7,Y7,Z7,A8,B8,C8,D8,E8,F8,G8,H8,I8,J8,K8,L8,M8,N8,O8,P8,Q8,R8,S8,T8,U8,V8,W8,X8,Y8,Z8,A9,B9,C9,D9,E9,F9,G9,H9,I9,J9,K9,L9,M9,N9,O9,P9,Q9,R9,S9,T9,U9,V9,W9,X9,Y9,Z9,A10,B10,C10,D10,E10,F10,G10,H10,I10,J10,K10,L10,M10,N10,O10,P10,Q10,R10,S10,T10,U10,V10,W10,X10,Y10,Z10,A11,B11,C11,D11,E11,F11,G11,H11,I11,J11,K11,L11,M11,N11,O11,P11,Q11,R11,S11,T11,U11,V11,W11,X11,Y11,Z11,A12,B12,C12,D12,E12,F12,G12,H12,I12,J12,K12,L12,M12,N12,O12,P12,Q12,R12,S12,T12,U12,V12,W12,X12,Y12,Z12,A13,B13,C13,D13,E13,F13,G13,H13,I13,J13,K13,L13,M13,N13,O13,P13,Q13,R13,S13,T13,U13,V13,W13,X13,Y13,Z13,A14,B14,C14,D14,E14,F14,G14,H14,I14,J14,K14,L14,M14,N14,O14,P14,Q14,R14,S14,T14,U14,V14,W14,X14,Y14,Z14,A15,B15,C15,D15,E15,F15,G15,H15,I15,J15,K15,L15,M15,N15,O15,P15,Q15,R15,S15,T15,U15,V15,W15,X15,Y15,Z15,A16,B16,C16,D16,E16,F16,G16,H16,I16,J16,K16,L16,M16,N16,O16,P16,Q16,R16,S16,T16,U16,V16,W16,X16,Y16,Z16,A17,B17,C17,D17,E17,F17,G17,H17,I17,J17,K17,L17,M17,N17,O17,P17,Q17,R17,S17,T17,U17,V17,W17,X17,Y17,Z17,A18,B18,C18,D18,E18,F18,G18,H18,I18,J18,K18,L18,M18,N18,O18,P18,Q18,R18,S18,T18,U18,V18,W18,X18,Y18,Z18,A19,B19,C19,D19,E19,F19,G19,H19,I19,J19,K19,L19,M19,N19,O19,P19,Q19,R19,S19,T19],U19).r9(A,B) <=> r8(A,B).r8([X9,W9,V9,U9,T9,S9,R9,Q9,P9,O9,N9,M9,L9,K9,J9,I9,H9,G9,F9,E9,D9,C9,B9,A9,Z8,Y8,X8,W8,V8,U8,T8,S8,R8,Q8,P8,O8,N8,M8,L8,K8,J8,I8,H8,G8,F8,E8,D8,C8,B8,A8,Z7,Y7,X7,W7,V7,U7,T7,S7,R7,Q7,P7,O7,N7,M7,L7,K7,J7,I7,H7,G7,F7,E7,D7,C7,B7,A7,Z6,Y6,X6,W6,V6,U6,T6,S6,R6,Q6,P6,O6,N6,M6,L6,K6,J6,I6,H6,G6,F6,E6,D6,C6,B6,A6,Z5,Y5,X5,W5,V5,U5,T5,S5,R5,Q5,P5,O5,N5,M5,L5,K5,J5,I5,H5,G5,F5,E5,D5,C5,B5,A5,Z4,Y4,X4,W4,V4,U4,T4,S4,R4,Q4,P4,O4,N4,M4,L4,K4,J4,I4,H4,G4,F4,E4,D4,C4,B4,A4,Z3,Y3,X3,W3,V3,U3,T3,S3,R3,Q3,P3,O3,N3,M3,L3,K3,J3,I3,H3,G3,F3,E3,D3,C3,B3,A3,Z2,Y2,X2,W2,V2,U2,T2,S2,R2,Q2,P2,O2,N2,M2,L2,K2,J2,I2,H2,G2,F2,E2,D2,C2,B2,A2,Z1,Y1,X1,W1,V1,U1,T1,S1,R1,Q1,P1,O1,N1,M1,L1,K1,J1,I1,H1,G1,F1,E1,D1,C1,B1,A1,Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C|A],Y9) <=> r7(A,B),append(B,[C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2,N2,O2,P2,Q2,R2,S2,T2,U2,V2,W2,X2,Y2,Z2,A3,B3,C3,D3,E3,F3,G3,H3,I3,J3,K3,L3,M3,N3,O3,P3,Q3,R3,S3,T3,U3,V3,W3,X3,Y3,Z3,A4,B4,C4,D4,E4,F4,G4,H4,I4,J4,K4,L4,M4,N4,O4,P4,Q4,R4,S4,T4,U4,V4,W4,X4,Y4,Z4,A5,B5,C5,D5,E5,F5,G5,H5,I5,J5,K5,L5,M5,N5,O5,P5,Q5,R5,S5,T5,U5,V5,W5,X5,Y5,Z5,A6,B6,C6,D6,E6,F6,G6,H6,I6,J6,K6,L6,M6,N6,O6,P6,Q6,R6,S6,T6,U6,V6,W6,X6,Y6,Z6,A7,B7,C7,D7,E7,F7,G7,H7,I7,J7,K7,L7,M7,N7,O7,P7,Q7,R7,S7,T7,U7,V7,W7,X7,Y7,Z7,A8,B8,C8,D8,E8,F8,G8,H8,I8,J8,K8,L8,M8,N8,O8,P8,Q8,R8,S8,T8,U8,V8,W8,X8,Y8,Z8,A9,B9,C9,D9,E9,F9,G9,H9,I9,J9,K9,L9,M9,N9,O9,P9,Q9,R9,S9,T9,U9,V9,W9,X9],Y9).r8(A,B) <=> r7(A,B).r7([Z4,Y4,X4,W4,V4,U4,T4,S4,R4,Q4,P4,O4,N4,M4,L4,K4,J4,I4,H4,G4,F4,E4,D4,C4,B4,A4,Z3,Y3,X3,W3,V3,U3,T3,S3,R3,Q3,P3,O3,N3,M3,L3,K3,J3,I3,H3,G3,F3,E3,D3,C3,B3,A3,Z2,Y2,X2,W2,V2,U2,T2,S2,R2,Q2,P2,O2,N2,M2,L2,K2,J2,I2,H2,G2,F2,E2,D2,C2,B2,A2,Z1,Y1,X1,W1,V1,U1,T1,S1,R1,Q1,P1,O1,N1,M1,L1,K1,J1,I1,H1,G1,F1,E1,D1,C1,B1,A1,Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C|A],A5) <=> r6(A,B),append(B,[C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2,N2,O2,P2,Q2,R2,S2,T2,U2,V2,W2,X2,Y2,Z2,A3,B3,C3,D3,E3,F3,G3,H3,I3,J3,K3,L3,M3,N3,O3,P3,Q3,R3,S3,T3,U3,V3,W3,X3,Y3,Z3,A4,B4,C4,D4,E4,F4,G4,H4,I4,J4,K4,L4,M4,N4,O4,P4,Q4,R4,S4,T4,U4,V4,W4,X4,Y4,Z4],A5).r7(A,B) <=> r6(A,B).r6([N2,M2,L2,K2,J2,I2,H2,G2,F2,E2,D2,C2,B2,A2,Z1,Y1,X1,W1,V1,U1,T1,S1,R1,Q1,P1,O1,N1,M1,L1,K1,J1,I1,H1,G1,F1,E1,D1,C1,B1,A1,Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C|A],O2) <=> r5(A,B),append(B,[C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2,N2],O2).r6(A,B) <=> r5(A,B).r5([H1,G1,F1,E1,D1,C1,B1,A1,Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C|A],I1) <=> r4(A,B),append(B,[C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1],I1).r5(A,B) <=> r4(A,B).r4([R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C|A],S) <=> r3(A,B),append(B,[C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R],S).r4(A,B) <=> r3(A,B).r3([J,I,H,G,F,E,D,C|A],K) <=> r2(A,B),append(B,[C,D,E,F,G,H,I,J],K).r3(A,B) <=> r2(A,B).r2([F,E,D,C|A],G) <=> r1(A,B),append(B,[C,D,E,F],G).r2(A,B) <=> r1(A,B).r1([D,C|A],E) <=> r0(A,B),append(B,[C,D],E).r1(A,B) <=> r0(A,B).r0([C|A],D) <=> r(A,B),append(B,[C],D).r0(A,B) <=> r(A,B).r([],D) <=> D=[].r10([L39,K39,J39,I39,H39,G39,F39,E39,D39,C39,B39,A39,Z38,Y38,X38,W38,V38,U38,T38,S38,R38,Q38,P38,O38,N38,M38,L38,K38,J38,I38,H38,G38,F38,E38,D38,C38,B38,A38,Z37,Y37,X37,W37,V37,U37,T37,S37,R37,Q37,P37,O37,N37,M37,L37,K37,J37,I37,H37,G37,F37,E37,D37,C37,B37,A37,Z36,Y36,X36,W36,V36,U36,T36,S36,R36,Q36,P36,O36,N36,M36,L36,K36,J36,I36,H36,G36,F36,E36,D36,C36,B36,A36,Z35,Y35,X35,W35,V35,U35,T35,S35,R35,Q35,P35,O35,N35,M35,L35,K35,J35,I35,H35,G35,F35,E35,D35,C35,B35,A35,Z34,Y34,X34,W34,V34,U34,T34,S34,R34,Q34,P34,O34,N34,M34,L34,K34,J34,I34,H34,G34,F34,E34,D34,C34,B34,A34,Z33,Y33,X33,W33,V33,U33,T33,S33,R33,Q33,P33,O33,N33,M33,L33,K33,J33,I33,H33,G33,F33,E33,D33,C33,B33,A33,Z32,Y32,X32,W32,V32,U32,T32,S32,R32,Q32,P32,O32,N32,M32,L32,K32,J32,I32,H32,G32,F32,E32,D32,C32,B32,A32,Z31,Y31,X31,W31,V31,U31,T31,S31,R31,Q31,P31,O31,N31,M31,L31,K31,J31,I31,H31,G31,F31,E31,D31,C31,B31,A31,Z30,Y30,X30,W30,V30,U30,T30,S30,R30,Q30,P30,O30,N30,M30,L30,K30,J30,I30,H30,G30,F30,E30,D30,C30,B30,A30,Z29,Y29,X29,W29,V29,U29,T29,S29,R29,Q29,P29,O29,N29,M29,L29,K29,J29,I29,H29,G29,F29,E29,D29,C29,B29,A29,Z28,Y28,X28,W28,V28,U28,T28,S28,R28,Q28,P28,O28,N28,M28,L28,K28,J28,I28,H28,G28,F28,E28,D28,C28,B28,A28,Z27,Y27,X27,W27,V27,U27,T27,S27,R27,Q27,P27,O27,N27,M27,L27,K27,J27,I27,H27,G27,F27,E27,D27,C27,B27,A27,Z26,Y26,X26,W26,V26,U26,T26,S26,R26,Q26,P26,O26,N26,M26,L26,K26,J26,I26,H26,G26,F26,E26,D26,C26,B26,A26,Z25,Y25,X25,W25,V25,U25,T25,S25,R25,Q25,P25,O25,N25,M25,L25,K25,J25,I25,H25,G25,F25,E25,D25,C25,B25,A25,Z24,Y24,X24,W24,V24,U24,T24,S24,R24,Q24,P24,O24,N24,M24,L24,K24,J24,I24,H24,G24,F24,E24,D24,C24,B24,A24,Z23,Y23,X23,W23,V23,U23,T23,S23,R23,Q23,P23,O23,N23,M23,L23,K23,J23,I23,H23,G23,F23,E23,D23,C23,B23,A23,Z22,Y22,X22,W22,V22,U22,T22,S22,R22,Q22,P22,O22,N22,M22,L22,K22,J22,I22,H22,G22,F22,E22,D22,C22,B22,A22,Z21,Y21,X21,W21,V21,U21,T21,S21,R21,Q21,P21,O21,N21,M21,L21,K21,J21,I21,H21,G21,F21,E21,D21,C21,B21,A21,Z20,Y20,X20,W20,V20,U20,T20,S20,R20,Q20,P20,O20,N20,M20,L20,K20,J20,I20,H20,G20,F20,E20,D20,C20,B20,A20,Z19,Y19,X19,W19,V19,U19,T19,S19,R19,Q19,P19,O19,N19,M19,L19,K19,J19,I19,H19,G19,F19,E19,D19,C19,B19,A19,Z18,Y18,X18,W18,V18,U18,T18,S18,R18,Q18,P18,O18,N18,M18,L18,K18,J18,I18,H18,G18,F18,E18,D18,C18,B18,A18,Z17,Y17,X17,W17,V17,U17,T17,S17,R17,Q17,P17,O17,N17,M17,L17,K17,J17,I17,H17,G17,F17,E17,D17,C17,B17,A17,Z16,Y16,X16,W16,V16,U16,T16,S16,R16,Q16,P16,O16,N16,M16,L16,K16,J16,I16,H16,G16,F16,E16,D16,C16,B16,A16,Z15,Y15,X15,W15,V15,U15,T15,S15,R15,Q15,P15,O15,N15,M15,L15,K15,J15,I15,H15,G15,F15,E15,D15,C15,B15,A15,Z14,Y14,X14,W14,V14,U14,T14,S14,R14,Q14,P14,O14,N14,M14,L14,K14,J14,I14,H14,G14,F14,E14,D14,C14,B14,A14,Z13,Y13,X13,W13,V13,U13,T13,S13,R13,Q13,P13,O13,N13,M13,L13,K13,J13,I13,H13,G13,F13,E13,D13,C13,B13,A13,Z12,Y12,X12,W12,V12,U12,T12,S12,R12,Q12,P12,O12,N12,M12,L12,K12,J12,I12,H12,G12,F12,E12,D12,C12,B12,A12,Z11,Y11,X11,W11,V11,U11,T11,S11,R11,Q11,P11,O11,N11,M11,L11,K11,J11,I11,H11,G11,F11,E11,D11,C11,B11,A11,Z10,Y10,X10,W10,V10,U10,T10,S10,R10,Q10,P10,O10,N10,M10,L10,K10,J10,I10,H10,G10,F10,E10,D10,C10,B10,A10,Z9,Y9,X9,W9,V9,U9,T9,S9,R9,Q9,P9,O9,N9,M9,L9,K9,J9,I9,H9,G9,F9,E9,D9,C9,B9,A9,Z8,Y8,X8,W8,V8,U8,T8,S8,R8,Q8,P8,O8,N8,M8,L8,K8,J8,I8,H8,G8,F8,E8,D8,C8,B8,A8,Z7,Y7,X7,W7,V7,U7,T7,S7,R7,Q7,P7,O7,N7,M7,L7,K7,J7,I7,H7,G7,F7,E7,D7,C7,B7,A7,Z6,Y6,X6,W6,V6,U6,T6,S6,R6,Q6,P6,O6,N6,M6,L6,K6,J6,I6,H6,G6,F6,E6,D6,C6,B6,A6,Z5,Y5,X5,W5,V5,U5,T5,S5,R5,Q5,P5,O5,N5,M5,L5,K5,J5,I5,H5,G5,F5,E5,D5,C5,B5,A5,Z4,Y4,X4,W4,V4,U4,T4,S4,R4,Q4,P4,O4,N4,M4,L4,K4,J4,I4,H4,G4,F4,E4,D4,C4,B4,A4,Z3,Y3,X3,W3,V3,U3,T3,S3,R3,Q3,P3,O3,N3,M3,L3,K3,J3,I3,H3,G3,F3,E3,D3,C3,B3,A3,Z2,Y2,X2,W2,V2,U2,T2,S2,R2,Q2,P2,O2,N2,M2,L2,K2,J2,I2,H2,G2,F2,E2,D2,C2,B2,A2,Z1,Y1,X1,W1,V1,U1,T1,S1,R1,Q1,P1,O1,N1,M1,L1,K1,J1,I1,H1,G1,F1,E1,D1,C1,B1,A1,Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C|A],M39) <=> r9(A,B),append(B,[C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2,N2,O2,P2,Q2,R2,S2,T2,U2,V2,W2,X2,Y2,Z2,A3,B3,C3,D3,E3,F3,G3,H3,I3,J3,K3,L3,M3,N3,O3,P3,Q3,R3,S3,T3,U3,V3,W3,X3,Y3,Z3,A4,B4,C4,D4,E4,F4,G4,H4,I4,J4,K4,L4,M4,N4,O4,P4,Q4,R4,S4,T4,U4,V4,W4,X4,Y4,Z4,A5,B5,C5,D5,E5,F5,G5,H5,I5,J5,K5,L5,M5,N5,O5,P5,Q5,R5,S5,T5,U5,V5,W5,X5,Y5,Z5,A6,B6,C6,D6,E6,F6,G6,H6,I6,J6,K6,L6,M6,N6,O6,P6,Q6,R6,S6,T6,U6,V6,W6,X6,Y6,Z6,A7,B7,C7,D7,E7,F7,G7,H7,I7,J7,K7,L7,M7,N7,O7,P7,Q7,R7,S7,T7,U7,V7,W7,X7,Y7,Z7,A8,B8,C8,D8,E8,F8,G8,H8,I8,J8,K8,L8,M8,N8,O8,P8,Q8,R8,S8,T8,U8,V8,W8,X8,Y8,Z8,A9,B9,C9,D9,E9,F9,G9,H9,I9,J9,K9,L9,M9,N9,O9,P9,Q9,R9,S9,T9,U9,V9,W9,X9,Y9,Z9,A10,B10,C10,D10,E10,F10,G10,H10,I10,J10,K10,L10,M10,N10,O10,P10,Q10,R10,S10,T10,U10,V10,W10,X10,Y10,Z10,A11,B11,C11,D11,E11,F11,G11,H11,I11,J11,K11,L11,M11,N11,O11,P11,Q11,R11,S11,T11,U11,V11,W11,X11,Y11,Z11,A12,B12,C12,D12,E12,F12,G12,H12,I12,J12,K12,L12,M12,N12,O12,P12,Q12,R12,S12,T12,U12,V12,W12,X12,Y12,Z12,A13,B13,C13,D13,E13,F13,G13,H13,I13,J13,K13,L13,M13,N13,O13,P13,Q13,R13,S13,T13,U13,V13,W13,X13,Y13,Z13,A14,B14,C14,D14,E14,F14,G14,H14,I14,J14,K14,L14,M14,N14,O14,P14,Q14,R14,S14,T14,U14,V14,W14,X14,Y14,Z14,A15,B15,C15,D15,E15,F15,G15,H15,I15,J15,K15,L15,M15,N15,O15,P15,Q15,R15,S15,T15,U15,V15,W15,X15,Y15,Z15,A16,B16,C16,D16,E16,F16,G16,H16,I16,J16,K16,L16,M16,N16,O16,P16,Q16,R16,S16,T16,U16,V16,W16,X16,Y16,Z16,A17,B17,C17,D17,E17,F17,G17,H17,I17,J17,K17,L17,M17,N17,O17,P17,Q17,R17,S17,T17,U17,V17,W17,X17,Y17,Z17,A18,B18,C18,D18,E18,F18,G18,H18,I18,J18,K18,L18,M18,N18,O18,P18,Q18,R18,S18,T18,U18,V18,W18,X18,Y18,Z18,A19,B19,C19,D19,E19,F19,G19,H19,I19,J19,K19,L19,M19,N19,O19,P19,Q19,R19,S19,T19,U19,V19,W19,X19,Y19,Z19,A20,B20,C20,D20,E20,F20,G20,H20,I20,J20,K20,L20,M20,N20,O20,P20,Q20,R20,S20,T20,U20,V20,W20,X20,Y20,Z20,A21,B21,C21,D21,E21,F21,G21,H21,I21,J21,K21,L21,M21,N21,O21,P21,Q21,R21,S21,T21,U21,V21,W21,X21,Y21,Z21,A22,B22,C22,D22,E22,F22,G22,H22,I22,J22,K22,L22,M22,N22,O22,P22,Q22,R22,S22,T22,U22,V22,W22,X22,Y22,Z22,A23,B23,C23,D23,E23,F23,G23,H23,I23,J23,K23,L23,M23,N23,O23,P23,Q23,R23,S23,T23,U23,V23,W23,X23,Y23,Z23,A24,B24,C24,D24,E24,F24,G24,H24,I24,J24,K24,L24,M24,N24,O24,P24,Q24,R24,S24,T24,U24,V24,W24,X24,Y24,Z24,A25,B25,C25,D25,E25,F25,G25,H25,I25,J25,K25,L25,M25,N25,O25,P25,Q25,R25,S25,T25,U25,V25,W25,X25,Y25,Z25,A26,B26,C26,D26,E26,F26,G26,H26,I26,J26,K26,L26,M26,N26,O26,P26,Q26,R26,S26,T26,U26,V26,W26,X26,Y26,Z26,A27,B27,C27,D27,E27,F27,G27,H27,I27,J27,K27,L27,M27,N27,O27,P27,Q27,R27,S27,T27,U27,V27,W27,X27,Y27,Z27,A28,B28,C28,D28,E28,F28,G28,H28,I28,J28,K28,L28,M28,N28,O28,P28,Q28,R28,S28,T28,U28,V28,W28,X28,Y28,Z28,A29,B29,C29,D29,E29,F29,G29,H29,I29,J29,K29,L29,M29,N29,O29,P29,Q29,R29,S29,T29,U29,V29,W29,X29,Y29,Z29,A30,B30,C30,D30,E30,F30,G30,H30,I30,J30,K30,L30,M30,N30,O30,P30,Q30,R30,S30,T30,U30,V30,W30,X30,Y30,Z30,A31,B31,C31,D31,E31,F31,G31,H31,I31,J31,K31,L31,M31,N31,O31,P31,Q31,R31,S31,T31,U31,V31,W31,X31,Y31,Z31,A32,B32,C32,D32,E32,F32,G32,H32,I32,J32,K32,L32,M32,N32,O32,P32,Q32,R32,S32,T32,U32,V32,W32,X32,Y32,Z32,A33,B33,C33,D33,E33,F33,G33,H33,I33,J33,K33,L33,M33,N33,O33,P33,Q33,R33,S33,T33,U33,V33,W33,X33,Y33,Z33,A34,B34,C34,D34,E34,F34,G34,H34,I34,J34,K34,L34,M34,N34,O34,P34,Q34,R34,S34,T34,U34,V34,W34,X34,Y34,Z34,A35,B35,C35,D35,E35,F35,G35,H35,I35,J35,K35,L35,M35,N35,O35,P35,Q35,R35,S35,T35,U35,V35,W35,X35,Y35,Z35,A36,B36,C36,D36,E36,F36,G36,H36,I36,J36,K36,L36,M36,N36,O36,P36,Q36,R36,S36,T36,U36,V36,W36,X36,Y36,Z36,A37,B37,C37,D37,E37,F37,G37,H37,I37,J37,K37,L37,M37,N37,O37,P37,Q37,R37,S37,T37,U37,V37,W37,X37,Y37,Z37,A38,B38,C38,D38,E38,F38,G38,H38,I38,J38,K38,L38,M38,N38,O38,P38,Q38,R38,S38,T38,U38,V38,W38,X38,Y38,Z38,A39,B39,C39,D39,E39,F39,G39,H39,I39,J39,K39,L39],M39).r10(A,B) <=> r9(A,B).r9([T19,S19,R19,Q19,P19,O19,N19,M19,L19,K19,J19,I19,H19,G19,F19,E19,D19,C19,B19,A19,Z18,Y18,X18,W18,V18,U18,T18,S18,R18,Q18,P18,O18,N18,M18,L18,K18,J18,I18,H18,G18,F18,E18,D18,C18,B18,A18,Z17,Y17,X17,W17,V17,U17,T17,S17,R17,Q17,P17,O17,N17,M17,L17,K17,J17,I17,H17,G17,F17,E17,D17,C17,B17,A17,Z16,Y16,X16,W16,V16,U16,T16,S16,R16,Q16,P16,O16,N16,M16,L16,K16,J16,I16,H16,G16,F16,E16,D16,C16,B16,A16,Z15,Y15,X15,W15,V15,U15,T15,S15,R15,Q15,P15,O15,N15,M15,L15,K15,J15,I15,H15,G15,F15,E15,D15,C15,B15,A15,Z14,Y14,X14,W14,V14,U14,T14,S14,R14,Q14,P14,O14,N14,M14,L14,K14,J14,I14,H14,G14,F14,E14,D14,C14,B14,A14,Z13,Y13,X13,W13,V13,U13,T13,S13,R13,Q13,P13,O13,N13,M13,L13,K13,J13,I13,H13,G13,F13,E13,D13,C13,B13,A13,Z12,Y12,X12,W12,V12,U12,T12,S12,R12,Q12,P12,O12,N12,M12,L12,K12,J12,I12,H12,G12,F12,E12,D12,C12,B12,A12,Z11,Y11,X11,W11,V11,U11,T11,S11,R11,Q11,P11,O11,N11,M11,L11,K11,J11,I11,H11,G11,F11,E11,D11,C11,B11,A11,Z10,Y10,X10,W10,V10,U10,T10,S10,R10,Q10,P10,O10,N10,M10,L10,K10,J10,I10,H10,G10,F10,E10,D10,C10,B10,A10,Z9,Y9,X9,W9,V9,U9,T9,S9,R9,Q9,P9,O9,N9,M9,L9,K9,J9,I9,H9,G9,F9,E9,D9,C9,B9,A9,Z8,Y8,X8,W8,V8,U8,T8,S8,R8,Q8,P8,O8,N8,M8,L8,K8,J8,I8,H8,G8,F8,E8,D8,C8,B8,A8,Z7,Y7,X7,W7,V7,U7,T7,S7,R7,Q7,P7,O7,N7,M7,L7,K7,J7,I7,H7,G7,F7,E7,D7,C7,B7,A7,Z6,Y6,X6,W6,V6,U6,T6,S6,R6,Q6,P6,O6,N6,M6,L6,K6,J6,I6,H6,G6,F6,E6,D6,C6,B6,A6,Z5,Y5,X5,W5,V5,U5,T5,S5,R5,Q5,P5,O5,N5,M5,L5,K5,J5,I5,H5,G5,F5,E5,D5,C5,B5,A5,Z4,Y4,X4,W4,V4,U4,T4,S4,R4,Q4,P4,O4,N4,M4,L4,K4,J4,I4,H4,G4,F4,E4,D4,C4,B4,A4,Z3,Y3,X3,W3,V3,U3,T3,S3,R3,Q3,P3,O3,N3,M3,L3,K3,J3,I3,H3,G3,F3,E3,D3,C3,B3,A3,Z2,Y2,X2,W2,V2,U2,T2,S2,R2,Q2,P2,O2,N2,M2,L2,K2,J2,I2,H2,G2,F2,E2,D2,C2,B2,A2,Z1,Y1,X1,W1,V1,U1,T1,S1,R1,Q1,P1,O1,N1,M1,L1,K1,J1,I1,H1,G1,F1,E1,D1,C1,B1,A1,Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C|A],U19) <=> r8(A,B),append(B,[C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2,N2,O2,P2,Q2,R2,S2,T2,U2,V2,W2,X2,Y2,Z2,A3,B3,C3,D3,E3,F3,G3,H3,I3,J3,K3,L3,M3,N3,O3,P3,Q3,R3,S3,T3,U3,V3,W3,X3,Y3,Z3,A4,B4,C4,D4,E4,F4,G4,H4,I4,J4,K4,L4,M4,N4,O4,P4,Q4,R4,S4,T4,U4,V4,W4,X4,Y4,Z4,A5,B5,C5,D5,E5,F5,G5,H5,I5,J5,K5,L5,M5,N5,O5,P5,Q5,R5,S5,T5,U5,V5,W5,X5,Y5,Z5,A6,B6,C6,D6,E6,F6,G6,H6,I6,J6,K6,L6,M6,N6,O6,P6,Q6,R6,S6,T6,U6,V6,W6,X6,Y6,Z6,A7,B7,C7,D7,E7,F7,G7,H7,I7,J7,K7,L7,M7,N7,O7,P7,Q7,R7,S7,T7,U7,V7,W7,X7,Y7,Z7,A8,B8,C8,D8,E8,F8,G8,H8,I8,J8,K8,L8,M8,N8,O8,P8,Q8,R8,S8,T8,U8,V8,W8,X8,Y8,Z8,A9,B9,C9,D9,E9,F9,G9,H9,I9,J9,K9,L9,M9,N9,O9,P9,Q9,R9,S9,T9,U9,V9,W9,X9,Y9,Z9,A10,B10,C10,D10,E10,F10,G10,H10,I10,J10,K10,L10,M10,N10,O10,P10,Q10,R10,S10,T10,U10,V10,W10,X10,Y10,Z10,A11,B11,C11,D11,E11,F11,G11,H11,I11,J11,K11,L11,M11,N11,O11,P11,Q11,R11,S11,T11,U11,V11,W11,X11,Y11,Z11,A12,B12,C12,D12,E12,F12,G12,H12,I12,J12,K12,L12,M12,N12,O12,P12,Q12,R12,S12,T12,U12,V12,W12,X12,Y12,Z12,A13,B13,C13,D13,E13,F13,G13,H13,I13,J13,K13,L13,M13,N13,O13,P13,Q13,R13,S13,T13,U13,V13,W13,X13,Y13,Z13,A14,B14,C14,D14,E14,F14,G14,H14,I14,J14,K14,L14,M14,N14,O14,P14,Q14,R14,S14,T14,U14,V14,W14,X14,Y14,Z14,A15,B15,C15,D15,E15,F15,G15,H15,I15,J15,K15,L15,M15,N15,O15,P15,Q15,R15,S15,T15,U15,V15,W15,X15,Y15,Z15,A16,B16,C16,D16,E16,F16,G16,H16,I16,J16,K16,L16,M16,N16,O16,P16,Q16,R16,S16,T16,U16,V16,W16,X16,Y16,Z16,A17,B17,C17,D17,E17,F17,G17,H17,I17,J17,K17,L17,M17,N17,O17,P17,Q17,R17,S17,T17,U17,V17,W17,X17,Y17,Z17,A18,B18,C18,D18,E18,F18,G18,H18,I18,J18,K18,L18,M18,N18,O18,P18,Q18,R18,S18,T18,U18,V18,W18,X18,Y18,Z18,A19,B19,C19,D19,E19,F19,G19,H19,I19,J19,K19,L19,M19,N19,O19,P19,Q19,R19,S19,T19],U19).r9(A,B) <=> r8(A,B).r8([X9,W9,V9,U9,T9,S9,R9,Q9,P9,O9,N9,M9,L9,K9,J9,I9,H9,G9,F9,E9,D9,C9,B9,A9,Z8,Y8,X8,W8,V8,U8,T8,S8,R8,Q8,P8,O8,N8,M8,L8,K8,J8,I8,H8,G8,F8,E8,D8,C8,B8,A8,Z7,Y7,X7,W7,V7,U7,T7,S7,R7,Q7,P7,O7,N7,M7,L7,K7,J7,I7,H7,G7,F7,E7,D7,C7,B7,A7,Z6,Y6,X6,W6,V6,U6,T6,S6,R6,Q6,P6,O6,N6,M6,L6,K6,J6,I6,H6,G6,F6,E6,D6,C6,B6,A6,Z5,Y5,X5,W5,V5,U5,T5,S5,R5,Q5,P5,O5,N5,M5,L5,K5,J5,I5,H5,G5,F5,E5,D5,C5,B5,A5,Z4,Y4,X4,W4,V4,U4,T4,S4,R4,Q4,P4,O4,N4,M4,L4,K4,J4,I4,H4,G4,F4,E4,D4,C4,B4,A4,Z3,Y3,X3,W3,V3,U3,T3,S3,R3,Q3,P3,O3,N3,M3,L3,K3,J3,I3,H3,G3,F3,E3,D3,C3,B3,A3,Z2,Y2,X2,W2,V2,U2,T2,S2,R2,Q2,P2,O2,N2,M2,L2,K2,J2,I2,H2,G2,F2,E2,D2,C2,B2,A2,Z1,Y1,X1,W1,V1,U1,T1,S1,R1,Q1,P1,O1,N1,M1,L1,K1,J1,I1,H1,G1,F1,E1,D1,C1,B1,A1,Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C|A],Y9) <=> r7(A,B),append(B,[C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2,N2,O2,P2,Q2,R2,S2,T2,U2,V2,W2,X2,Y2,Z2,A3,B3,C3,D3,E3,F3,G3,H3,I3,J3,K3,L3,M3,N3,O3,P3,Q3,R3,S3,T3,U3,V3,W3,X3,Y3,Z3,A4,B4,C4,D4,E4,F4,G4,H4,I4,J4,K4,L4,M4,N4,O4,P4,Q4,R4,S4,T4,U4,V4,W4,X4,Y4,Z4,A5,B5,C5,D5,E5,F5,G5,H5,I5,J5,K5,L5,M5,N5,O5,P5,Q5,R5,S5,T5,U5,V5,W5,X5,Y5,Z5,A6,B6,C6,D6,E6,F6,G6,H6,I6,J6,K6,L6,M6,N6,O6,P6,Q6,R6,S6,T6,U6,V6,W6,X6,Y6,Z6,A7,B7,C7,D7,E7,F7,G7,H7,I7,J7,K7,L7,M7,N7,O7,P7,Q7,R7,S7,T7,U7,V7,W7,X7,Y7,Z7,A8,B8,C8,D8,E8,F8,G8,H8,I8,J8,K8,L8,M8,N8,O8,P8,Q8,R8,S8,T8,U8,V8,W8,X8,Y8,Z8,A9,B9,C9,D9,E9,F9,G9,H9,I9,J9,K9,L9,M9,N9,O9,P9,Q9,R9,S9,T9,U9,V9,W9,X9],Y9).r8(A,B) <=> r7(A,B).r7([Z4,Y4,X4,W4,V4,U4,T4,S4,R4,Q4,P4,O4,N4,M4,L4,K4,J4,I4,H4,G4,F4,E4,D4,C4,B4,A4,Z3,Y3,X3,W3,V3,U3,T3,S3,R3,Q3,P3,O3,N3,M3,L3,K3,J3,I3,H3,G3,F3,E3,D3,C3,B3,A3,Z2,Y2,X2,W2,V2,U2,T2,S2,R2,Q2,P2,O2,N2,M2,L2,K2,J2,I2,H2,G2,F2,E2,D2,C2,B2,A2,Z1,Y1,X1,W1,V1,U1,T1,S1,R1,Q1,P1,O1,N1,M1,L1,K1,J1,I1,H1,G1,F1,E1,D1,C1,B1,A1,Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C|A],A5) <=> r6(A,B),append(B,[C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2,N2,O2,P2,Q2,R2,S2,T2,U2,V2,W2,X2,Y2,Z2,A3,B3,C3,D3,E3,F3,G3,H3,I3,J3,K3,L3,M3,N3,O3,P3,Q3,R3,S3,T3,U3,V3,W3,X3,Y3,Z3,A4,B4,C4,D4,E4,F4,G4,H4,I4,J4,K4,L4,M4,N4,O4,P4,Q4,R4,S4,T4,U4,V4,W4,X4,Y4,Z4],A5).r7(A,B) <=> r6(A,B).r6([N2,M2,L2,K2,J2,I2,H2,G2,F2,E2,D2,C2,B2,A2,Z1,Y1,X1,W1,V1,U1,T1,S1,R1,Q1,P1,O1,N1,M1,L1,K1,J1,I1,H1,G1,F1,E1,D1,C1,B1,A1,Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C|A],O2) <=> r5(A,B),append(B,[C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1,I1,J1,K1,L1,M1,N1,O1,P1,Q1,R1,S1,T1,U1,V1,W1,X1,Y1,Z1,A2,B2,C2,D2,E2,F2,G2,H2,I2,J2,K2,L2,M2,N2],O2).r6(A,B) <=> r5(A,B).r5([H1,G1,F1,E1,D1,C1,B1,A1,Z,Y,X,W,V,U,T,S,R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C|A],I1) <=> r4(A,B),append(B,[C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z,A1,B1,C1,D1,E1,F1,G1,H1],I1).r5(A,B) <=> r4(A,B).r4([R,Q,P,O,N,M,L,K,J,I,H,G,F,E,D,C|A],S) <=> r3(A,B),append(B,[C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R],S).r4(A,B) <=> r3(A,B).r3([J,I,H,G,F,E,D,C|A],K) <=> r2(A,B),append(B,[C,D,E,F,G,H,I,J],K).r3(A,B) <=> r2(A,B).r2([F,E,D,C|A],G) <=> r1(A,B),append(B,[C,D,E,F],G).r2(A,B) <=> r1(A,B).r1([D,C|A],E) <=> r0(A,B),append(B,[C,D],E).r1(A,B) <=> r0(A,B).r0([C|A],D) <=> r(A,B),append(B,[C],D).r0(A,B) <=> r(A,B).r([],D) <=> D=[].