We consider the system Applicative_05__Ex5Folding. Alphabet: 0 : [] --> c add : [] --> a -> c -> c cons : [a * b] --> b fold : [a -> c -> c * c] --> b -> c mul : [] --> a -> c -> c nil : [] --> b plus : [c * c] --> c prod : [] --> b -> c s : [c] --> c sum : [] --> b -> c times : [c * c] --> c Rules: fold(f, x) nil => x fold(f, x) cons(y, z) => f y (fold(f, x) z) plus(0, x) => x plus(s(x), y) => s(plus(x, y)) times(0, x) => 0 times(s(x), y) => plus(times(x, y), y) sum => fold(add, 0) prod => fold(mul, s(0)) This AFS is converted to an AFSM simply by replacing all free variables by meta-variables (with arity 0). We use rule removal, following [Kop12, Theorem 2.23]. This gives the following requirements (possibly using Theorems 2.25 and 2.26 in [Kop12]): fold(F, X) nil >? X fold(F, X) cons(Y, Z) >? F Y (fold(F, X) Z) plus(0, X) >? X plus(s(X), Y) >? s(plus(X, Y)) times(0, X) >? 0 times(s(X), Y) >? plus(times(X, Y), Y) sum >? fold(add, 0) prod >? fold(mul, s(0)) We use a recursive path ordering as defined in [Kop12, Chapter 5]. Argument functions: [[0]] = _|_ [[add]] = _|_ [[mul]] = _|_ We choose Lex = {s} and Mul = {@_{o -> o -> o}, @_{o -> o}, cons, fold, nil, plus, prod, sum, times}, and the following precedence: cons > nil > prod > sum > fold > @_{o -> o -> o} > @_{o -> o} > times > plus > s Taking the argument function into account, and fixing the greater / greater equal choices, the constraints can be denoted as follows: @_{o -> o}(fold(F, X), nil) >= X @_{o -> o}(fold(F, X), cons(Y, Z)) > @_{o -> o}(@_{o -> o -> o}(F, Y), @_{o -> o}(fold(F, X), Z)) plus(_|_, X) > X plus(s(X), Y) >= s(plus(X, Y)) times(_|_, X) > _|_ times(s(X), Y) > plus(times(X, Y), Y) sum > fold(_|_, _|_) prod >= fold(_|_, s(_|_)) With these choices, we have: 1] @_{o -> o}(fold(F, X), nil) >= X because [2], by (Star) 2] @_{o -> o}*(fold(F, X), nil) >= X because [3], by (Select) 3] fold(F, X) @_{o -> o}*(fold(F, X), nil) >= X because [4] 4] fold*(F, X, @_{o -> o}*(fold(F, X), nil)) >= X because [5], by (Select) 5] @_{o -> o}*(fold(F, X), nil) >= X because [6], by (Select) 6] fold(F, X) @_{o -> o}*(fold(F, X), nil) >= X because [7] 7] fold*(F, X, @_{o -> o}*(fold(F, X), nil)) >= X because [8], by (Select) 8] X >= X by (Meta) 9] @_{o -> o}(fold(F, X), cons(Y, Z)) > @_{o -> o}(@_{o -> o -> o}(F, Y), @_{o -> o}(fold(F, X), Z)) because [10], by definition 10] @_{o -> o}*(fold(F, X), cons(Y, Z)) >= @_{o -> o}(@_{o -> o -> o}(F, Y), @_{o -> o}(fold(F, X), Z)) because [11], by (Select) 11] fold(F, X) @_{o -> o}*(fold(F, X), cons(Y, Z)) >= @_{o -> o}(@_{o -> o -> o}(F, Y), @_{o -> o}(fold(F, X), Z)) because [12] 12] fold*(F, X, @_{o -> o}*(fold(F, X), cons(Y, Z))) >= @_{o -> o}(@_{o -> o -> o}(F, Y), @_{o -> o}(fold(F, X), Z)) because fold > @_{o -> o}, [13] and [21], by (Copy) 13] fold*(F, X, @_{o -> o}*(fold(F, X), cons(Y, Z))) >= @_{o -> o -> o}(F, Y) because fold > @_{o -> o -> o}, [14] and [16], by (Copy) 14] fold*(F, X, @_{o -> o}*(fold(F, X), cons(Y, Z))) >= F because [15], by (Select) 15] F >= F by (Meta) 16] fold*(F, X, @_{o -> o}*(fold(F, X), cons(Y, Z))) >= Y because [17], by (Select) 17] @_{o -> o}*(fold(F, X), cons(Y, Z)) >= Y because [18], by (Select) 18] cons(Y, Z) >= Y because [19], by (Star) 19] cons*(Y, Z) >= Y because [20], by (Select) 20] Y >= Y by (Meta) 21] fold*(F, X, @_{o -> o}*(fold(F, X), cons(Y, Z))) >= @_{o -> o}(fold(F, X), Z) because [22], by (Select) 22] @_{o -> o}*(fold(F, X), cons(Y, Z)) >= @_{o -> o}(fold(F, X), Z) because @_{o -> o} in Mul, [23] and [26], by (Stat) 23] fold(F, X) >= fold(F, X) because fold in Mul, [24] and [25], by (Fun) 24] F >= F by (Meta) 25] X >= X by (Meta) 26] cons(Y, Z) > Z because [27], by definition 27] cons*(Y, Z) >= Z because [28], by (Select) 28] Z >= Z by (Meta) 29] plus(_|_, X) > X because [30], by definition 30] plus*(_|_, X) >= X because [31], by (Select) 31] X >= X by (Meta) 32] plus(s(X), Y) >= s(plus(X, Y)) because [33], by (Star) 33] plus*(s(X), Y) >= s(plus(X, Y)) because plus > s and [34], by (Copy) 34] plus*(s(X), Y) >= plus(X, Y) because plus in Mul, [35] and [38], by (Stat) 35] s(X) > X because [36], by definition 36] s*(X) >= X because [37], by (Select) 37] X >= X by (Meta) 38] Y >= Y by (Meta) 39] times(_|_, X) > _|_ because [40], by definition 40] times*(_|_, X) >= _|_ by (Bot) 41] times(s(X), Y) > plus(times(X, Y), Y) because [42], by definition 42] times*(s(X), Y) >= plus(times(X, Y), Y) because times > plus, [43] and [48], by (Copy) 43] times*(s(X), Y) >= times(X, Y) because times in Mul, [44] and [47], by (Stat) 44] s(X) > X because [45], by definition 45] s*(X) >= X because [46], by (Select) 46] X >= X by (Meta) 47] Y >= Y by (Meta) 48] times*(s(X), Y) >= Y because [47], by (Select) 49] sum > fold(_|_, _|_) because [50], by definition 50] sum* >= fold(_|_, _|_) because sum > fold, [51] and [52], by (Copy) 51] sum* >= _|_ by (Bot) 52] sum* >= _|_ by (Bot) 53] prod >= fold(_|_, s(_|_)) because [54], by (Star) 54] prod* >= fold(_|_, s(_|_)) because prod > fold, [55] and [56], by (Copy) 55] prod* >= _|_ by (Bot) 56] prod* >= s(_|_) because prod > s and [57], by (Copy) 57] prod* >= _|_ by (Bot) We can thus remove the following rules: fold(F, X) cons(Y, Z) => F Y (fold(F, X) Z) plus(0, X) => X times(0, X) => 0 times(s(X), Y) => plus(times(X, Y), Y) sum => fold(add, 0) We use rule removal, following [Kop12, Theorem 2.23]. This gives the following requirements (possibly using Theorems 2.25 and 2.26 in [Kop12]): fold(F, X) nil >? X plus(s(X), Y) >? s(plus(X, Y)) prod >? fold(mul, s(0)) We orient these requirements with a polynomial interpretation in the natural numbers. The following interpretation satisfies the requirements: 0 = 0 fold = Lam[G0;y1;y2].2 + y1 + 3*y2 + G0(0,0) + 2*G0(y1,y2) + 2*G0(y2,y2) mul = Lam[y0;y1].0 nil = 3 plus = Lam[y0;y1].y1 + 3*y0 prod = Lam[y0].3 + 3*y0 s = Lam[y0].y0 Using this interpretation, the requirements translate to: [[fold(_F0, _x1) nil]] = 14 + x1 + F0(0,0) + 2*F0(3,3) + 2*F0(x1,3) > x1 = [[_x1]] [[plus(s(_x0), _x1)]] = x1 + 3*x0 >= x1 + 3*x0 = [[s(plus(_x0, _x1))]] [[prod]] = Lam[y0].3 + 3*y0 > Lam[y0].2 + 3*y0 = [[fold(mul, s(0))]] We can thus remove the following rules: fold(F, X) nil => X prod => fold(mul, s(0)) We use rule removal, following [Kop12, Theorem 2.23]. This gives the following requirements (possibly using Theorems 2.25 and 2.26 in [Kop12]): plus(s(X), Y) >? s(plus(X, Y)) We orient these requirements with a polynomial interpretation in the natural numbers. The following interpretation satisfies the requirements: plus = Lam[y0;y1].2*y1 + 3*y0 s = Lam[y0].2 + y0 Using this interpretation, the requirements translate to: [[plus(s(_x0), _x1)]] = 6 + 2*x1 + 3*x0 > 2 + 2*x1 + 3*x0 = [[s(plus(_x0, _x1))]] We can thus remove the following rules: plus(s(X), Y) => s(plus(X, Y)) All rules were succesfully removed. Thus, termination of the original system has been reduced to termination of the beta-rule, which is well-known to hold. +++ Citations +++ [Kop12] C. Kop. Higher Order Termination. PhD Thesis, 2012.