We consider the system qsort. Alphabet: 0 : [] --> nat app : [list * list] --> list cons : [nat * list] --> list false : [] --> bool filter : [nat -> bool * list] --> list gr : [nat * nat] --> bool if : [bool * list * list] --> list le : [nat * nat] --> bool nil : [] --> list qsort : [list] --> list s : [nat] --> nat true : [] --> bool Rules: if(true, x, y) => x if(false, x, y) => y app(nil, x) => x app(cons(x, y), z) => cons(x, app(y, z)) le(0, x) => true le(s(x), 0) => false le(s(x), s(y)) => le(x, y) gr(0, x) => false gr(s(x), 0) => true gr(s(x), s(y)) => gr(x, y) filter(f, nil) => nil filter(f, cons(x, y)) => if(f x, cons(x, filter(f, y)), filter(f, y)) qsort(nil) => nil qsort(cons(x, y)) => app(qsort(filter(/\z.le(z, x), y)), app(cons(x, nil), qsort(filter(/\u.gr(u, x), y)))) This AFS is converted to an AFSM simply by replacing all free variables by meta-variables (with arity 0). We observe that the rules contain a first-order subset: if(true, X, Y) => X if(false, X, Y) => Y app(nil, X) => X app(cons(X, Y), Z) => cons(X, app(Y, Z)) le(0, X) => true le(s(X), 0) => false le(s(X), s(Y)) => le(X, Y) gr(0, X) => false gr(s(X), 0) => true gr(s(X), s(Y)) => gr(X, Y) Moreover, the system is orthogonal. Thus, by [Kop12, Thm. 7.55], we may omit all first-order dependency pairs from the dependency pair problem (DP(R), R) if this first-order part is terminating when seen as a many-sorted first-order TRS. According to the external first-order termination prover, this system is indeed terminating: || proof of resources/system.trs || # AProVE Commit ID: d84c10301d352dfd14de2104819581f4682260f5 fuhs 20130616 || || || Termination w.r.t. Q of the given QTRS could be proven: || || (0) QTRS || (1) QTRSRRRProof [EQUIVALENT] || (2) QTRS || (3) RisEmptyProof [EQUIVALENT] || (4) YES || || || ---------------------------------------- || || (0) || Obligation: || Q restricted rewrite system: || The TRS R consists of the following rules: || || if(true, %X, %Y) -> %X || if(false, %X, %Y) -> %Y || app(nil, %X) -> %X || app(cons(%X, %Y), %Z) -> cons(%X, app(%Y, %Z)) || le(0, %X) -> true || le(s(%X), 0) -> false || le(s(%X), s(%Y)) -> le(%X, %Y) || gr(0, %X) -> false || gr(s(%X), 0) -> true || gr(s(%X), s(%Y)) -> gr(%X, %Y) || || Q is empty. || || ---------------------------------------- || || (1) QTRSRRRProof (EQUIVALENT) || Used ordering: || Knuth-Bendix order [KBO] with precedence:s_1 > gr_2 > if_3 > 0 > le_2 > app_2 > cons_2 > nil > false > true || || and weight map: || || true=2 || false=2 || nil=1 || 0=1 || s_1=0 || if_3=0 || app_2=0 || cons_2=0 || le_2=0 || gr_2=0 || || The variable weight is 1With this ordering the following rules can be removed by the rule removal processor [LPAR04] because they are oriented strictly: || || if(true, %X, %Y) -> %X || if(false, %X, %Y) -> %Y || app(nil, %X) -> %X || app(cons(%X, %Y), %Z) -> cons(%X, app(%Y, %Z)) || le(0, %X) -> true || le(s(%X), 0) -> false || le(s(%X), s(%Y)) -> le(%X, %Y) || gr(0, %X) -> false || gr(s(%X), 0) -> true || gr(s(%X), s(%Y)) -> gr(%X, %Y) || || || || || ---------------------------------------- || || (2) || Obligation: || Q restricted rewrite system: || R is empty. || Q is empty. || || ---------------------------------------- || || (3) RisEmptyProof (EQUIVALENT) || The TRS R is empty. Hence, termination is trivially proven. || ---------------------------------------- || || (4) || YES || We use the dependency pair framework as described in [Kop12, Ch. 6/7], with dynamic dependency pairs. After applying [Kop12, Thm. 7.22] to denote collapsing dependency pairs in an extended form, we thus obtain the following dependency pair problem (P_0, R_0, minimal, formative): Dependency Pairs P_0: 0] filter#(F, cons(X, Y)) =#> if#(F X, cons(X, filter(F, Y)), filter(F, Y)) 1] filter#(F, cons(X, Y)) =#> F(X) 2] filter#(F, cons(X, Y)) =#> filter#(F, Y) 3] filter#(F, cons(X, Y)) =#> filter#(F, Y) 4] qsort#(cons(X, Y)) =#> app#(qsort(filter(/\x.le(x, X), Y)), app(cons(X, nil), qsort(filter(/\y.gr(y, X), Y)))) 5] qsort#(cons(X, Y)) =#> qsort#(filter(/\x.le(x, X), Y)) 6] qsort#(cons(X, Y)) =#> filter#(/\x.le(x, X), Y) 7] qsort#(cons(X, Y)) =#> le#(x, X) 8] qsort#(cons(X, Y)) =#> app#(cons(X, nil), qsort(filter(/\x.gr(x, X), Y))) 9] qsort#(cons(X, Y)) =#> qsort#(filter(/\x.gr(x, X), Y)) 10] qsort#(cons(X, Y)) =#> filter#(/\x.gr(x, X), Y) 11] qsort#(cons(X, Y)) =#> gr#(x, X) Rules R_0: if(true, X, Y) => X if(false, X, Y) => Y app(nil, X) => X app(cons(X, Y), Z) => cons(X, app(Y, Z)) le(0, X) => true le(s(X), 0) => false le(s(X), s(Y)) => le(X, Y) gr(0, X) => false gr(s(X), 0) => true gr(s(X), s(Y)) => gr(X, Y) filter(F, nil) => nil filter(F, cons(X, Y)) => if(F X, cons(X, filter(F, Y)), filter(F, Y)) qsort(nil) => nil qsort(cons(X, Y)) => app(qsort(filter(/\x.le(x, X), Y)), app(cons(X, nil), qsort(filter(/\y.gr(y, X), Y)))) Thus, the original system is terminating if (P_0, R_0, minimal, formative) is finite. We consider the dependency pair problem (P_0, R_0, minimal, formative). We place the elements of P in a dependency graph approximation G (see e.g. [Kop12, Thm. 7.27, 7.29], as follows: * 0 : * 1 : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 * 2 : 0, 1, 2, 3 * 3 : 0, 1, 2, 3 * 4 : * 5 : 4, 5, 6, 7, 8, 9, 10, 11 * 6 : 0, 1, 2, 3 * 7 : * 8 : * 9 : 4, 5, 6, 7, 8, 9, 10, 11 * 10 : 0, 1, 2, 3 * 11 : This graph has the following strongly connected components: P_1: filter#(F, cons(X, Y)) =#> F(X) filter#(F, cons(X, Y)) =#> filter#(F, Y) filter#(F, cons(X, Y)) =#> filter#(F, Y) qsort#(cons(X, Y)) =#> qsort#(filter(/\x.le(x, X), Y)) qsort#(cons(X, Y)) =#> filter#(/\x.le(x, X), Y) qsort#(cons(X, Y)) =#> qsort#(filter(/\x.gr(x, X), Y)) qsort#(cons(X, Y)) =#> filter#(/\x.gr(x, X), Y) By [Kop12, Thm. 7.31], we may replace any dependency pair problem (P_0, R_0, m, f) by (P_1, R_0, m, f). Thus, the original system is terminating if (P_1, R_0, minimal, formative) is finite. We consider the dependency pair problem (P_1, R_0, minimal, formative). We will use the reduction pair processor [Kop12, Thm. 7.16]. As the system is abstraction-simple and the formative flag is set, it suffices to find a tagged reduction pair [Kop12, Def. 6.70]. Thus, we must orient: filter#(F, cons(X, Y)) >? F(X) filter#(F, cons(X, Y)) >? filter#(F, Y) filter#(F, cons(X, Y)) >? filter#(F, Y) qsort#(cons(X, Y)) >? qsort#(filter(/\x.le-(x, X), Y)) qsort#(cons(X, Y)) >? filter#(/\x.le-(x, X), Y) qsort#(cons(X, Y)) >? qsort#(filter(/\x.gr-(x, X), Y)) qsort#(cons(X, Y)) >? filter#(/\x.gr-(x, X), Y) if(true, X, Y) >= X if(false, X, Y) >= Y app(nil, X) >= X app(cons(X, Y), Z) >= cons(X, app(Y, Z)) le(0, X) >= true le(s(X), 0) >= false le(s(X), s(Y)) >= le(X, Y) gr(0, X) >= false gr(s(X), 0) >= true gr(s(X), s(Y)) >= gr(X, Y) filter(F, nil) >= nil filter(F, cons(X, Y)) >= if(F X, cons(X, filter(F, Y)), filter(F, Y)) qsort(nil) >= nil qsort(cons(X, Y)) >= app(qsort(filter(/\x.le-(x, X), Y)), app(cons(X, nil), qsort(filter(/\y.gr-(y, X), Y)))) gr-(X, Y) >= gr(X, Y) le-(X, Y) >= le(X, Y) Since this representation is not advantageous for the higher-order recursive path ordering, we present the strict requirements in their unextended form, which is not problematic since for any F, s and substituion gamma: (F s)gamma beta-reduces to F(s)gamma.) We use a recursive path ordering as defined in [Kop12, Chapter 5]. Argument functions: [[false]] = _|_ [[filter(x_1, x_2)]] = filter(x_2) [[if(x_1, x_2, x_3)]] = if(x_2, x_3) [[le(x_1, x_2)]] = le(x_1) [[nil]] = _|_ [[true]] = _|_ We choose Lex = {app} and Mul = {0, @_{o -> o}, cons, filter, filter#, gr, gr-, if, le, le-, qsort, qsort#, s}, and the following precedence: 0 > qsort > app > cons = filter > qsort# > gr- > gr > if > le- > le = s > filter# > @_{o -> o} Taking the argument function into account, and fixing the greater / greater equal choices, the constraints can be denoted as follows: filter#(F, cons(X, Y)) > @_{o -> o}(F, X) filter#(F, cons(X, Y)) >= filter#(F, Y) filter#(F, cons(X, Y)) >= filter#(F, Y) qsort#(cons(X, Y)) >= qsort#(filter(Y)) qsort#(cons(X, Y)) >= filter#(/\x.le-(x, X), Y) qsort#(cons(X, Y)) > qsort#(filter(Y)) qsort#(cons(X, Y)) >= filter#(/\x.gr-(x, X), Y) if(X, Y) >= X if(X, Y) >= Y app(_|_, X) >= X app(cons(X, Y), Z) >= cons(X, app(Y, Z)) le(0) >= _|_ le(s(X)) >= _|_ le(s(X)) >= le(X) gr(0, X) >= _|_ gr(s(X), 0) >= _|_ gr(s(X), s(Y)) >= gr(X, Y) filter(_|_) >= _|_ filter(cons(X, Y)) >= if(cons(X, filter(Y)), filter(Y)) qsort(_|_) >= _|_ qsort(cons(X, Y)) >= app(qsort(filter(Y)), app(cons(X, _|_), qsort(filter(Y)))) gr-(X, Y) >= gr(X, Y) le-(X, Y) >= le(X) With these choices, we have: 1] filter#(F, cons(X, Y)) > @_{o -> o}(F, X) because [2], by definition 2] filter#*(F, cons(X, Y)) >= @_{o -> o}(F, X) because filter# > @_{o -> o}, [3] and [5], by (Copy) 3] filter#*(F, cons(X, Y)) >= F because [4], by (Select) 4] F >= F by (Meta) 5] filter#*(F, cons(X, Y)) >= X because [6], by (Select) 6] cons(X, Y) >= X because [7], by (Star) 7] cons*(X, Y) >= X because [8], by (Select) 8] X >= X by (Meta) 9] filter#(F, cons(X, Y)) >= filter#(F, Y) because [10], by (Star) 10] filter#*(F, cons(X, Y)) >= filter#(F, Y) because filter# in Mul, [11] and [12], by (Stat) 11] F >= F by (Meta) 12] cons(X, Y) > Y because [13], by definition 13] cons*(X, Y) >= Y because [14], by (Select) 14] Y >= Y by (Meta) 15] filter#(F, cons(X, Y)) >= filter#(F, Y) because [10], by (Star) 16] qsort#(cons(X, Y)) >= qsort#(filter(Y)) because [17], by (Star) 17] qsort#*(cons(X, Y)) >= qsort#(filter(Y)) because qsort# in Mul and [18], by (Stat) 18] cons(X, Y) > filter(Y) because [19], by definition 19] cons*(X, Y) >= filter(Y) because cons = filter, cons in Mul and [20], by (Stat) 20] Y >= Y by (Meta) 21] qsort#(cons(X, Y)) >= filter#(/\x.le-(x, X), Y) because [22], by (Star) 22] qsort#*(cons(X, Y)) >= filter#(/\x.le-(x, X), Y) because qsort# > filter#, [23] and [31], by (Copy) 23] qsort#*(cons(X, Y)) >= /\y.le-(y, X) because [24], by (F-Abs) 24] qsort#*(cons(X, Y), x) >= le-(x, X) because qsort# > le-, [25] and [27], by (Copy) 25] qsort#*(cons(X, Y), x) >= x because [26], by (Select) 26] x >= x by (Var) 27] qsort#*(cons(X, Y), x) >= 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] qsort#*(cons(X, Y)) >= Y because [32], by (Select) 32] cons(X, Y) >= Y because [33], by (Star) 33] cons*(X, Y) >= Y because [20], by (Select) 34] qsort#(cons(X, Y)) > qsort#(filter(Y)) because [35], by definition 35] qsort#*(cons(X, Y)) >= qsort#(filter(Y)) because [36], by (Select) 36] cons(X, Y) >= qsort#(filter(Y)) because [37], by (Star) 37] cons*(X, Y) >= qsort#(filter(Y)) because cons > qsort# and [38], by (Copy) 38] cons*(X, Y) >= filter(Y) because cons = filter, cons in Mul and [20], by (Stat) 39] qsort#(cons(X, Y)) >= filter#(/\x.gr-(x, X), Y) because [40], by (Star) 40] qsort#*(cons(X, Y)) >= filter#(/\x.gr-(x, X), Y) because qsort# > filter#, [41] and [31], by (Copy) 41] qsort#*(cons(X, Y)) >= /\y.gr-(y, X) because [42], by (F-Abs) 42] qsort#*(cons(X, Y), x) >= gr-(x, X) because qsort# > gr-, [43] and [45], by (Copy) 43] qsort#*(cons(X, Y), x) >= x because [44], by (Select) 44] x >= x by (Var) 45] qsort#*(cons(X, Y), x) >= X because [28], by (Select) 46] if(X, Y) >= X because [47], by (Star) 47] if*(X, Y) >= X because [48], by (Select) 48] X >= X by (Meta) 49] if(X, Y) >= Y because [50], by (Star) 50] if*(X, Y) >= Y because [51], by (Select) 51] Y >= Y by (Meta) 52] app(_|_, X) >= X because [53], by (Star) 53] app*(_|_, X) >= X because [54], by (Select) 54] X >= X by (Meta) 55] app(cons(X, Y), Z) >= cons(X, app(Y, Z)) because [56], by (Star) 56] app*(cons(X, Y), Z) >= cons(X, app(Y, Z)) because app > cons, [57] and [61], by (Copy) 57] app*(cons(X, Y), Z) >= X because [58], by (Select) 58] cons(X, Y) >= X because [59], by (Star) 59] cons*(X, Y) >= X because [60], by (Select) 60] X >= X by (Meta) 61] app*(cons(X, Y), Z) >= app(Y, Z) because [62], [65] and [67], by (Stat) 62] cons(X, Y) > Y because [63], by definition 63] cons*(X, Y) >= Y because [64], by (Select) 64] Y >= Y by (Meta) 65] app*(cons(X, Y), Z) >= Y because [66], by (Select) 66] cons(X, Y) >= Y because [63], by (Star) 67] app*(cons(X, Y), Z) >= Z because [68], by (Select) 68] Z >= Z by (Meta) 69] le(0) >= _|_ by (Bot) 70] le(s(X)) >= _|_ by (Bot) 71] le(s(X)) >= le(X) because [72], by (Star) 72] le*(s(X)) >= le(X) because [73], by (Select) 73] s(X) >= le(X) because s = le, s in Mul and [74], by (Fun) 74] X >= X by (Meta) 75] gr(0, X) >= _|_ by (Bot) 76] gr(s(X), 0) >= _|_ by (Bot) 77] gr(s(X), s(Y)) >= gr(X, Y) because [78], by (Star) 78] gr*(s(X), s(Y)) >= gr(X, Y) because gr in Mul, [79] and [82], by (Stat) 79] s(X) >= X because [80], by (Star) 80] s*(X) >= X because [81], by (Select) 81] X >= X by (Meta) 82] s(Y) > Y because [83], by definition 83] s*(Y) >= Y because [84], by (Select) 84] Y >= Y by (Meta) 85] filter(_|_) >= _|_ by (Bot) 86] filter(cons(X, Y)) >= if(cons(X, filter(Y)), filter(Y)) because [87], by (Star) 87] filter*(cons(X, Y)) >= if(cons(X, filter(Y)), filter(Y)) because filter > if, [88] and [94], by (Copy) 88] filter*(cons(X, Y)) >= cons(X, filter(Y)) because filter = cons, filter in Mul, [89] and [91], by (Stat) 89] cons(X, Y) > X because [90], by definition 90] cons*(X, Y) >= X because [8], by (Select) 91] cons(X, Y) > filter(Y) because [92], by definition 92] cons*(X, Y) >= filter(Y) because cons = filter, cons in Mul and [93], by (Stat) 93] Y >= Y by (Meta) 94] filter*(cons(X, Y)) >= filter(Y) because filter in Mul and [12], by (Stat) 95] qsort(_|_) >= _|_ by (Bot) 96] qsort(cons(X, Y)) >= app(qsort(filter(Y)), app(cons(X, _|_), qsort(filter(Y)))) because [97], by (Star) 97] qsort*(cons(X, Y)) >= app(qsort(filter(Y)), app(cons(X, _|_), qsort(filter(Y)))) because qsort > app, [98] and [99], by (Copy) 98] qsort*(cons(X, Y)) >= qsort(filter(Y)) because qsort in Mul and [18], by (Stat) 99] qsort*(cons(X, Y)) >= app(cons(X, _|_), qsort(filter(Y))) because qsort > app, [100] and [104], by (Copy) 100] qsort*(cons(X, Y)) >= cons(X, _|_) because [101], by (Select) 101] cons(X, Y) >= cons(X, _|_) because cons in Mul, [102] and [103], by (Fun) 102] X >= X by (Meta) 103] Y >= _|_ by (Bot) 104] qsort*(cons(X, Y)) >= qsort(filter(Y)) because qsort in Mul and [105], by (Stat) 105] cons(X, Y) > filter(Y) because [38], by definition 106] gr-(X, Y) >= gr(X, Y) because [107], by (Star) 107] gr-*(X, Y) >= gr(X, Y) because gr- > gr, [108] and [110], by (Copy) 108] gr-*(X, Y) >= X because [109], by (Select) 109] X >= X by (Meta) 110] gr-*(X, Y) >= Y because [111], by (Select) 111] Y >= Y by (Meta) 112] le-(X, Y) >= le(X) because [113], by (Star) 113] le-*(X, Y) >= le(X) because le- > le and [114], by (Copy) 114] le-*(X, Y) >= X because [115], by (Select) 115] X >= X by (Meta) By the observations in [Kop12, Sec. 6.6], this reduction pair suffices; we may thus replace the dependency pair problem (P_1, R_0, minimal, formative) by (P_2, R_0, minimal, formative), where P_2 consists of: filter#(F, cons(X, Y)) =#> filter#(F, Y) filter#(F, cons(X, Y)) =#> filter#(F, Y) qsort#(cons(X, Y)) =#> qsort#(filter(/\x.le(x, X), Y)) qsort#(cons(X, Y)) =#> filter#(/\x.le(x, X), Y) qsort#(cons(X, Y)) =#> filter#(/\x.gr(x, X), Y) Thus, the original system is terminating if (P_2, R_0, minimal, formative) is finite. We consider the dependency pair problem (P_2, R_0, minimal, formative). We place the elements of P in a dependency graph approximation G (see e.g. [Kop12, Thm. 7.27, 7.29], as follows: * 0 : 0, 1 * 1 : 0, 1 * 2 : 2, 3, 4 * 3 : 0, 1 * 4 : 0, 1 This graph has the following strongly connected components: P_3: filter#(F, cons(X, Y)) =#> filter#(F, Y) filter#(F, cons(X, Y)) =#> filter#(F, Y) P_4: qsort#(cons(X, Y)) =#> qsort#(filter(/\x.le(x, X), Y)) By [Kop12, Thm. 7.31], we may replace any dependency pair problem (P_2, R_0, m, f) by (P_3, R_0, m, f) and (P_4, R_0, m, f). Thus, the original system is terminating if each of (P_3, R_0, minimal, formative) and (P_4, R_0, minimal, formative) is finite. We consider the dependency pair problem (P_4, R_0, minimal, formative). We will use the reduction pair processor [Kop12, Thm. 7.16]. It suffices to find a standard reduction pair [Kop12, Def. 6.69]. Thus, we must orient: qsort#(cons(X, Y)) >? qsort#(filter(/\x.le(x, X), Y)) if(true, X, Y) >= X if(false, X, Y) >= Y app(nil, X) >= X app(cons(X, Y), Z) >= cons(X, app(Y, Z)) le(0, X) >= true le(s(X), 0) >= false le(s(X), s(Y)) >= le(X, Y) gr(0, X) >= false gr(s(X), 0) >= true gr(s(X), s(Y)) >= gr(X, Y) filter(F, nil) >= nil filter(F, cons(X, Y)) >= if(F X, cons(X, filter(F, Y)), filter(F, Y)) qsort(nil) >= nil qsort(cons(X, Y)) >= app(qsort(filter(/\x.le(x, X), Y)), app(cons(X, nil), qsort(filter(/\y.gr(y, X), Y)))) Since this representation is not advantageous for the higher-order recursive path ordering, we present the strict requirements in their unextended form, which is not problematic since for any F, s and substituion gamma: (F s)gamma beta-reduces to F(s)gamma.) We use a recursive path ordering as defined in [Kop12, Chapter 5]. Argument functions: [[false]] = _|_ [[filter(x_1, x_2)]] = filter(x_2) [[gr(x_1, x_2)]] = gr(x_1) [[if(x_1, x_2, x_3)]] = if(x_2, x_3) [[nil]] = _|_ [[true]] = _|_ We choose Lex = {} and Mul = {0, @_{o -> o}, app, cons, filter, gr, if, le, qsort, qsort#, s}, and the following precedence: 0 > @_{o -> o} > le > qsort > app > cons = filter > if > qsort# > gr > s Taking the argument function into account, and fixing the greater / greater equal choices, the constraints can be denoted as follows: qsort#(cons(X, Y)) > qsort#(filter(Y)) if(X, Y) >= X if(X, Y) >= Y app(_|_, X) >= X app(cons(X, Y), Z) >= cons(X, app(Y, Z)) le(0, X) >= _|_ le(s(X), 0) >= _|_ le(s(X), s(Y)) >= le(X, Y) gr(0) >= _|_ gr(s(X)) >= _|_ gr(s(X)) >= gr(X) filter(_|_) >= _|_ filter(cons(X, Y)) >= if(cons(X, filter(Y)), filter(Y)) qsort(_|_) >= _|_ qsort(cons(X, Y)) >= app(qsort(filter(Y)), app(cons(X, _|_), qsort(filter(Y)))) With these choices, we have: 1] qsort#(cons(X, Y)) > qsort#(filter(Y)) because [2], by definition 2] qsort#*(cons(X, Y)) >= qsort#(filter(Y)) because [3], by (Select) 3] cons(X, Y) >= qsort#(filter(Y)) because [4], by (Star) 4] cons*(X, Y) >= qsort#(filter(Y)) because cons > qsort# and [5], by (Copy) 5] cons*(X, Y) >= filter(Y) because cons = filter, cons in Mul and [6], by (Stat) 6] Y >= Y by (Meta) 7] if(X, Y) >= X because [8], by (Star) 8] if*(X, Y) >= X because [9], by (Select) 9] X >= X by (Meta) 10] if(X, Y) >= Y because [11], by (Star) 11] if*(X, Y) >= Y because [12], by (Select) 12] Y >= Y by (Meta) 13] app(_|_, X) >= X because [14], by (Star) 14] app*(_|_, X) >= X because [15], by (Select) 15] X >= X by (Meta) 16] app(cons(X, Y), Z) >= cons(X, app(Y, Z)) because [17], by (Star) 17] app*(cons(X, Y), Z) >= cons(X, app(Y, Z)) because app > cons, [18] and [22], by (Copy) 18] app*(cons(X, Y), Z) >= X because [19], by (Select) 19] cons(X, Y) >= X because [20], by (Star) 20] cons*(X, Y) >= X because [21], by (Select) 21] X >= X by (Meta) 22] app*(cons(X, Y), Z) >= app(Y, Z) because app in Mul, [23] and [26], by (Stat) 23] cons(X, Y) > Y because [24], by definition 24] cons*(X, Y) >= Y because [25], by (Select) 25] Y >= Y by (Meta) 26] Z >= Z by (Meta) 27] le(0, X) >= _|_ by (Bot) 28] le(s(X), 0) >= _|_ by (Bot) 29] le(s(X), s(Y)) >= le(X, Y) because [30], by (Star) 30] le*(s(X), s(Y)) >= le(X, Y) because le in Mul, [31] and [34], by (Stat) 31] s(X) >= X because [32], by (Star) 32] s*(X) >= X because [33], by (Select) 33] X >= X by (Meta) 34] s(Y) > Y because [35], by definition 35] s*(Y) >= Y because [36], by (Select) 36] Y >= Y by (Meta) 37] gr(0) >= _|_ by (Bot) 38] gr(s(X)) >= _|_ by (Bot) 39] gr(s(X)) >= gr(X) because gr in Mul and [40], by (Fun) 40] s(X) >= X because [41], by (Star) 41] s*(X) >= X because [42], by (Select) 42] X >= X by (Meta) 43] filter(_|_) >= _|_ by (Bot) 44] filter(cons(X, Y)) >= if(cons(X, filter(Y)), filter(Y)) because [45], by (Star) 45] filter*(cons(X, Y)) >= if(cons(X, filter(Y)), filter(Y)) because filter > if, [46] and [53], by (Copy) 46] filter*(cons(X, Y)) >= cons(X, filter(Y)) because filter = cons, filter in Mul, [47] and [50], by (Stat) 47] cons(X, Y) > X because [48], by definition 48] cons*(X, Y) >= X because [49], by (Select) 49] X >= X by (Meta) 50] cons(X, Y) > filter(Y) because [51], by definition 51] cons*(X, Y) >= filter(Y) because cons = filter, cons in Mul and [52], by (Stat) 52] Y >= Y by (Meta) 53] filter*(cons(X, Y)) >= filter(Y) because [54], by (Select) 54] cons(X, Y) >= filter(Y) because [51], by (Star) 55] qsort(_|_) >= _|_ by (Bot) 56] qsort(cons(X, Y)) >= app(qsort(filter(Y)), app(cons(X, _|_), qsort(filter(Y)))) because [57], by (Star) 57] qsort*(cons(X, Y)) >= app(qsort(filter(Y)), app(cons(X, _|_), qsort(filter(Y)))) because qsort > app, [58] and [60], by (Copy) 58] qsort*(cons(X, Y)) >= qsort(filter(Y)) because qsort in Mul and [59], by (Stat) 59] cons(X, Y) > filter(Y) because [5], by definition 60] qsort*(cons(X, Y)) >= app(cons(X, _|_), qsort(filter(Y))) because qsort > app, [61] and [65], by (Copy) 61] qsort*(cons(X, Y)) >= cons(X, _|_) because [62], by (Select) 62] cons(X, Y) >= cons(X, _|_) because cons in Mul, [63] and [64], by (Fun) 63] X >= X by (Meta) 64] Y >= _|_ by (Bot) 65] qsort*(cons(X, Y)) >= qsort(filter(Y)) because qsort in Mul and [66], by (Stat) 66] cons(X, Y) > filter(Y) because [67], by definition 67] cons*(X, Y) >= filter(Y) because cons = filter, cons in Mul and [6], by (Stat) By the observations in [Kop12, Sec. 6.6], this reduction pair suffices; we may thus replace a dependency pair problem (P_4, R_0) by ({}, R_0). By the empty set processor [Kop12, Thm. 7.15] this problem may be immediately removed. Thus, the original system is terminating if (P_3, R_0, minimal, formative) is finite. We consider the dependency pair problem (P_3, R_0, minimal, formative). We apply the subterm criterion with the following projection function: nu(filter#) = 2 Thus, we can orient the dependency pairs as follows: nu(filter#(F, cons(X, Y))) = cons(X, Y) |> Y = nu(filter#(F, Y)) nu(filter#(F, cons(X, Y))) = cons(X, Y) |> Y = nu(filter#(F, Y)) By [FuhKop19, Thm. 61], we may replace a dependency pair problem (P_3, R_0, minimal, f) by ({}, R_0, minimal, f). By the empty set processor [Kop12, Thm. 7.15] this problem may be immediately removed. As all dependency pair problems were succesfully simplified with sound (and complete) processors until nothing remained, we conclude termination. +++ Citations +++ [FuhKop19] C. Fuhs, and C. Kop. A static higher-order dependency pair framework. In Proceedings of ESOP 2019, 2019. [Kop12] C. Kop. Higher Order Termination. PhD Thesis, 2012.