We consider the system h03. Alphabet: 0 : [] --> c 1 : [] --> c add : [] --> c -> a -> c cons : [a * b] --> b fold : [c -> a -> c * b * c] --> c mul : [] --> c -> a -> c nil : [] --> b prod : [b] --> c sum : [b] --> c xap : [c -> a -> c * c] --> a -> c yap : [a -> c * a] --> c Rules: fold(/\x./\y.yap(xap(f, x), y), nil, z) => z fold(/\x./\y.yap(xap(f, x), y), cons(z, u), v) => fold(/\w./\x'.yap(xap(f, w), x'), u, yap(xap(f, v), z)) sum(x) => fold(/\y./\z.yap(xap(add, y), z), x, 0) fold(mul, x, 1) => prod(x) xap(f, x) => f x yap(f, x) => f x This AFS is converted to an AFSM simply by replacing all free variables by meta-variables (with arity 0). Symbol xap is an encoding for application that is only used in innocuous ways. We can simplify the program (without losing non-termination) by removing it. This gives: Alphabet: 0 : [] --> c 1 : [] --> c add : [c] --> a -> c cons : [a * b] --> b fold : [c -> a -> c * b * c] --> c mul : [] --> c -> a -> c nil : [] --> b prod : [b] --> c sum : [b] --> c yap : [a -> c * a] --> c Rules: fold(/\x./\y.yap(F(x), y), nil, X) => X fold(/\x./\y.yap(F(x), y), cons(X, Y), Z) => fold(/\z./\u.yap(F(z), u), Y, yap(F(Z), X)) sum(X) => fold(/\x./\y.yap(add(x), y), X, 0) fold(mul, X, 1) => prod(X) yap(F, X) => F X 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(/\x./\y.yap(F(x), y), nil, X) >? X fold(/\x./\y.yap(F(x), y), cons(X, Y), Z) >? fold(/\z./\u.yap(F(z), u), Y, yap(F(Z), X)) sum(X) >? fold(/\x./\y.yap(add(x), y), X, 0) fold(mul, X, 1) >? prod(X) yap(F, X) >? F X We use a recursive path ordering as defined in [Kop12, Chapter 5]. Argument functions: [[0]] = _|_ [[fold(x_1, x_2, x_3)]] = fold(x_2, x_3, x_1) [[prod(x_1)]] = x_1 We choose Lex = {fold} and Mul = {1, @_{o -> o}, add, cons, mul, nil, sum, yap}, and the following precedence: 1 > mul > nil > cons > sum > add > fold > yap > @_{o -> o} Taking the argument function into account, and fixing the greater / greater equal choices, the constraints can be denoted as follows: fold(/\x./\y.yap(F(x), y), nil, X) >= X fold(/\x./\y.yap(F(x), y), cons(X, Y), Z) > fold(/\x./\y.yap(F(x), y), Y, yap(F(Z), X)) sum(X) >= fold(/\x./\y.yap(add(x), y), X, _|_) fold(mul, X, 1) > X yap(F, X) >= @_{o -> o}(F, X) With these choices, we have: 1] fold(/\x./\y.yap(F(x), y), nil, X) >= X because [2], by (Star) 2] fold*(/\x./\y.yap(F(x), y), nil, X) >= X because [3], by (Select) 3] X >= X by (Meta) 4] fold(/\x./\y.yap(F(x), y), cons(X, Y), Z) > fold(/\x./\y.yap(F(x), y), Y, yap(F(Z), X)) because [5], by definition 5] fold*(/\x./\y.yap(F(x), y), cons(X, Y), Z) >= fold(/\x./\y.yap(F(x), y), Y, yap(F(Z), X)) because [6], by (Select) 6] yap(F(fold*(/\x./\y.yap(F(x), y), cons(X, Y), Z)), fold*(/\z./\u.yap(F(z), u), cons(X, Y), Z)) >= fold(/\x./\y.yap(F(x), y), Y, yap(F(Z), X)) because [7], by (Star) 7] yap*(F(fold*(/\x./\y.yap(F(x), y), cons(X, Y), Z)), fold*(/\z./\u.yap(F(z), u), cons(X, Y), Z)) >= fold(/\x./\y.yap(F(x), y), Y, yap(F(Z), X)) because [8], by (Select) 8] fold*(/\x./\y.yap(F(x), y), cons(X, Y), Z) >= fold(/\x./\y.yap(F(x), y), Y, yap(F(Z), X)) because [9], [12], [19] and [21], by (Stat) 9] cons(X, Y) > Y because [10], by definition 10] cons*(X, Y) >= Y because [11], by (Select) 11] Y >= Y by (Meta) 12] fold*(/\x./\y.yap(F(x), y), cons(X, Y), Z) >= /\x./\y.yap(F(x), y) because [13], by (Select) 13] /\x./\z.yap(F(x), z) >= /\x./\z.yap(F(x), z) because [14], by (Abs) 14] /\z.yap(F(y), z) >= /\z.yap(F(y), z) because [15], by (Abs) 15] yap(F(y), x) >= yap(F(y), x) because yap in Mul, [16] and [18], by (Fun) 16] F(y) >= F(y) because [17], by (Meta) 17] y >= y by (Var) 18] x >= x by (Var) 19] fold*(/\z./\u.yap(F(z), u), cons(X, Y), Z) >= Y because [20], by (Select) 20] cons(X, Y) >= Y because [10], by (Star) 21] fold*(/\z./\u.yap(F(z), u), cons(X, Y), Z) >= yap(F(Z), X) because fold > yap, [22] and [27], by (Copy) 22] fold*(/\z./\u.yap(F(z), u), cons(X, Y), Z) >= F(Z) because [23], by (Select) 23] /\z.yap(F(fold*(/\u./\v.yap(F(u), v), cons(X, Y), Z)), z) >= F(Z) because [24], by (Eta)[Kop13:2] 24] F(fold*(/\z./\u.yap(F(z), u), cons(X, Y), Z)) >= F(Z) because [25], by (Meta) 25] fold*(/\z./\u.yap(F(z), u), cons(X, Y), Z) >= Z because [26], by (Select) 26] Z >= Z by (Meta) 27] fold*(/\z./\u.yap(F(z), u), cons(X, Y), Z) >= X because [28], by (Select) 28] cons(X, Y) >= X because [29], by (Star) 29] cons*(X, Y) >= X because [30], by (Select) 30] X >= X by (Meta) 31] sum(X) >= fold(/\x./\y.yap(add(x), y), X, _|_) because [32], by (Star) 32] sum*(X) >= fold(/\x./\y.yap(add(x), y), X, _|_) because sum > fold, [33], [41] and [43], by (Copy) 33] sum*(X) >= /\y./\z.yap(add(y), z) because [34], by (F-Abs) 34] sum*(X, x) >= /\z.yap(add(x), z) because [35], by (F-Abs) 35] sum*(X, x, y) >= yap(add(x), y) because sum > yap, [36] and [39], by (Copy) 36] sum*(X, x, y) >= add(x) because sum > add and [37], by (Copy) 37] sum*(X, x, y) >= x because [38], by (Select) 38] x >= x by (Var) 39] sum*(X, x, y) >= y because [40], by (Select) 40] y >= y by (Var) 41] sum*(X) >= X because [42], by (Select) 42] X >= X by (Meta) 43] sum*(X) >= _|_ by (Bot) 44] fold(mul, X, 1) > X because [45], by definition 45] fold*(mul, X, 1) >= X because [46], by (Select) 46] X >= X by (Meta) 47] yap(F, X) >= @_{o -> o}(F, X) because [48], by (Star) 48] yap*(F, X) >= @_{o -> o}(F, X) because yap > @_{o -> o}, [49] and [51], by (Copy) 49] yap*(F, X) >= F because [50], by (Select) 50] F >= F by (Meta) 51] yap*(F, X) >= X because [52], by (Select) 52] X >= X by (Meta) We can thus remove the following rules: fold(/\x./\y.yap(F(x), y), cons(X, Y), Z) => fold(/\z./\u.yap(F(z), u), Y, yap(F(Z), X)) fold(mul, X, 1) => prod(X) 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(/\x./\y.yap(F(x), y), nil, X) >? X sum(X) >? fold(/\x./\y.yap(add(x), y), X, 0) yap(F, X) >? F X We orient these requirements with a polynomial interpretation in the natural numbers. The following interpretation satisfies the requirements: 0 = 0 add = \y0y1.y0 fold = \G0y1y2.y1 + y2 + G0(0,0) nil = 3 sum = \y0.3 + 3y0 yap = \G0y1.y1 + G0(y1) Using this interpretation, the requirements translate to: [[fold(/\x./\y.yap(_F0(x), y), nil, _x1)]] = 3 + x1 + F0(0,0) > x1 = [[_x1]] [[sum(_x0)]] = 3 + 3x0 > x0 = [[fold(/\x./\y.yap(add(x), y), _x0, 0)]] [[yap(_F0, _x1)]] = x1 + F0(x1) >= x1 + F0(x1) = [[_F0 _x1]] We can thus remove the following rules: fold(/\x./\y.yap(F(x), y), nil, X) => X sum(X) => fold(/\x./\y.yap(add(x), y), X, 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]): yap(F, X) >? F X We orient these requirements with a polynomial interpretation in the natural numbers. The following interpretation satisfies the requirements: yap = \G0y1.1 + y1 + G0(y1) Using this interpretation, the requirements translate to: [[yap(_F0, _x1)]] = 1 + x1 + F0(x1) > x1 + F0(x1) = [[_F0 _x1]] We can thus remove the following rules: yap(F, X) => F X 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. [Kop13:2] C. Kop. StarHorpo with an Eta-Rule. Unpublished manuscript, http://cl-informatik.uibk.ac.at/users/kop/etahorpo.pdf, 2013.