Here, we list all benchmarks from Complexity_C_Non_Linear and provide sources and context for all 20 programs. The benchmarks can be downloaded here. To test our benchmarks, we suggest to use our web interface for C programs.
twn01.c
This benchmark is a simple linear loop which does not have a ranking function over the reals (see Leike & Heizmann here, Thm. 4.5) but can be solved by our twn-technique.
int twn01(int a, int b) {
while(a < b && a > 0) {
a = 3*a;
b = 2*b;
}
return 0;
}
twn02.c
This benchmark is an advanced, slightly changed version of twn01.c
by adding non-linear arithmetic.
int twn02(int a, int b, int c) {
while(a < b*b && a > 0) {
a = 5*a + c*c;
b = 2*b;
}
return 0;
}
twn03.c
This program consists of two consecutive loops.
The first loop can be solved by MΦRFs of depth 2 (see Ben-Amram & Genaim here, Table 1 - Loop 20) or our twn-technique.
The second loop corresponds to the loop in twn02.c
.
int twn03(int a, int b, int c) {
if(a > 0) {
while(c > 0) {
a = a + c;
c = c - 1;
}
while(a < b*b) {
a = 5*a + c*c;
b = 2*b;
}
}
return 0;
}
twn04.c
This example consists of two nested loops.
The inner loop corresponds to the loop in twn02.c
.
The outer loop is evaluated at most c
times and resets both variables a
and b
in every iteration.
int twn04(int a, int b, int c, int d, int e) {
if(d > 0) {
a = d;
b = e;
while(c > 0) {
while(a < b*b && a > 0) {
a = 5*a + c*c;
b = 2*b;
}
a = d;
b = e;
c = c - 1;
}
}
return 0;
}
twn05.c
This benchmark is an advanced version of twn04.c
.
While twn04.c
contains two loops, this program consists of three loops by adding the loop at Line 6 to Line 9.
This additional loop can be solved by MΦRFs of depth 2 (see Ben-Amram & Genaim here, Table 1 - Loop 20) or our twn-technique.
int twn05(int a, int b, int c, int d, int e, int f) {
if(f > 0) {
a = d;
b = e;
while(f > 0) {
while(c > 0) {
a = a + c;
c = c - 1;
}
while(a < b*b && a > 0) {
a = 5*a + c*c;
b = 2*b;
}
a = d;
b = e;
c = f;
f = f - 1;
}
}
return 0;
}
twn06.c
This benchmark is similar to twn05.c
.
However, as the second inner loop, instead of a twn-loop, this example uses a solvable loop (see Xu & Li here, Ex. 3.3 & 3.4).
int twn06(int a, int b, int c, int d, int e, int f) {
if(d > 0) {
a = d;
b = e;
while(c > 0) {
while(c > 0) {
a = a + c;
c = c - 1;
}
c = f;
while(b*b > 1 && a*c + 2*a > 0) {
a = a;
int b1 = b;
int c1 = c;
b = 3*b1 - 4*c1;
c = 4*b1 - 3*c1;
d = 5*d;
e = 5*e - a*a;
}
a = d;
b = e;
f = f - 1;
}
}
return 0;
}
twn07.c
This program consists of two consecutive loops such that one needs to compute size bounds for the first loop with non-linear arithmetic in order to handle the second loop.
int twn07(int a, int b, int c) {
while(a > 0) {
a = a - 1;
b = b + c*c*c;
}
while(b > 0) {
b = b - 1;
}
return 0;
}
twn08.c
This example combines an integer program which needs control-flow refinement (see Giesl et al. here, Fig.7) to be solved and the twn-loop twn02.c
.
extern int __VERIFIER_nondet_int(void);
void f(int x, int y, int f, int a, int b, int c) {
int u = __VERIFIER_nondet_int();
int v = __VERIFIER_nondet_int();
x = u;
f = v;
while (1) {
if (1<=x && x<=3 && f == 0) {
x = x+1;
v = __VERIFIER_nondet_int();
f = v;
} else if (y>1 && f == 1) {
y = y-1;
v = __VERIFIER_nondet_int();
f = v;
} else {
while(a < b*b && a > 0) {
a = 5*a + c*c;
b = 2*b;
}
break;
}
}
}
twn09.c
Our approach can not only handle twn-self-loops but simple cycles which correspond to twn-loops.
To this end, we introduce the following benchmark where we update a
and c
twice in the inner loop.
int twn09(int a, int b, int c) {
if(a > 0) {
while(c > 0) {
a = a + c;
c = c - 1;
}
if(c <= 0) {
while(a < b*b) {
c = -2*b;
a = 5*a;
c = b + c;
a = a + c*c*c*c;
b = 2*b;
c = b + c;
}
}
}
return 0;
}
twn10.c
This program is a twn-loop (see Frohn & Giesl here, Ex. 2).
int twn10(int a, int b, int c, int d) {
while(c + d > 0) {
a = 2;
b = b + 1;
c = -2*c - a;
d = b;
}
return 0;
}
twn11.c
This benchmark corresponds to a loop which can be transformed into a twn-loop by automorphisms (see Frohn et al. here, Ex. 24).
int twn11(int a, int b, int c) {
while(4*b*b + a + b + c > 0) {
a = a + 8*a*b*b + 16*b*b*b + 16*b*b*c;
b = b - a*a - 4*a*b - 4*a*c - 4*b*b - 8*b*c - 4*c*c;
c = c - 4*a*b*b - 8*b*b*b - 8*b*b*c + a*a + 4*a*b + 4*a*c + 4*b*b + 8*b*c + 4*c*c;
}
return 0;
}
twn12.c
This program is a non-terminating twn-loop (see Frohn et al. here, Ex. 24).
int twn12(int a, int b, int c) {
while(a + b*b > 0) {
a = a + b*b*c;
b = b - 2*c*c;
c = c;
}
return 0;
}
twn13.c
This benchmark is a terminating version of twn12.c
.
We have added the precondition and invariant c < 0
.
Thus, the value of a
always decreases, and at some point is less than -b*b
.
int twn13(int a, int b, int c) {
if (c < 0) {
while(a + b*b > 0) {
a = a + b*b*c;
b = b - 2*c*c;
c = c;
}
}
return 0;
}
twn14.c
This program is a simplified implementation of our running example (see Fig. 1).
Here, we only consider the condition d > 0
, respectively the path evaluating t1, and not the path evaluating t₃ and t₄.
This example differs from the benchmark twn14.koat
.
int twn14(int a, int b, int c, int d, int e) {
while(a > 0) {
b = a;
c = e;
if(d > 0) {
while (b != 0 && b*b + d*d*d*d*d < c) {
b = -2*b;
c = 3*c - d*d*d;
}
}
a = a - 1;
}
return 0;
}
twn15.c
This benchmark is an implementation of our running example (see Fig. 1).
Here, we consider both paths t₂ and t₃ * t₄.
This example differs from the benchmark twn15.koat
.
Note that here, we do not consider the non-deterministic choice as in Fig. 1.
Our implementation instead first regards the path t₃ * t₄ and only if this path is not applicable, then the path t₂ is evaluated.
int twn15(int a, int b, int c, int d, int e) {
while(a > 0) {
b = a;
c = e;
if(-5 <= d && d <= 5) {
while (b != 0 && b*b + d*d*d*d*d < c) {
b = -2*b;
c = 3*c - d*d*d;
}
}
else if (d > 0) {
while (b != 0 && b*b + d*d*d*d*d < c) {
b = -2*b;
c = 3*c - d*d*d;
}
}
a = a - 1;
}
return 0;
}
twn16.c
This program has constant runtime and our twn-approach indeed infers a constant runtime bound. In contrast, linear ranking functions only infer a linear bound for this example. Therefore, both configurations KoAT2 + TWN + RF or KoAT2 + TWN + MΦRF5 infer a non-constant linear runtime bound here, since they always search for linear ranking functions first and only if they do not succeed in inferring a finite runtime bound, then these configurations apply our twn-technique.
int twn16(int y) {
while(y <= 42 && y > 0) {
y = 2*y;
}
return 0;
}
twn17.c
This benchmark is an advanced version of twn15.c
.
Here, we added a fourth consecutive loop which decreases the value of b
by 1 until it is non-positive.
However, as the value of b
can have exponential size w.r.t. the initial values (since both inner loops double the absolute value of b
iteratively), this benchmark has exponential runtime.
int twn17(int a, int b, int c, int d, int e) {
while(a > 0) {
b = a;
c = e;
if(-5 <= d && d <= 5) {
while (b != 0 && b*b + d*d*d*d*d < c) {
b = -2*b;
c = 3*c - d*d*d;
}
}
else if (d > 0) {
while (b != 0 && b*b + d*d*d*d*d < c) {
b = -2*b;
c = 3*c - d*d*d;
}
}
a = a - 1;
}
while(b > 0) {
b = b - 1;
}
return 0;
}
twn18.c
This program is a solvable loop (see Xu & Li here, Ex. 3.3 & 3.4).
int twn18(int a, int b, int c, int d, int e) {
while(b*b > 1 && a*c + 2*a > 0) {
a = a;
int b1 = b;
int c1 = c;
b = 3*b1 - 4*c1;
c = 4*b1 - 3*c1;
d = 5*d;
e = 5*e - a*a;
}
return 0;
}
twn19.c
This benchmark corresponds to the isolated transition t₅ as in Fig. 1. Note that only our tool with our twn-technique is able to solve this example, i.e., tools based on ranking functions already fail on t₅ alone.
int twn19(int a, int b, int c) {
if(c > 0) {
while(a*a + c*c*c*c*c < b && a != 0) {
a = -2*a;
b = 3*b - 2*c*c*c;
c = c;
}
}
return 0;
}
twn20.c
This program corresponds to the chained version of the isolated transition t₅, i.e., it corresponds to t₅ * t₅, as in Fig. 1. Again, only our tool with our twn-technique is able to solve this example.
int twn20(int a, int b, int c) {
if(c > 0) {
while(a*a + c*c*c*c*c < b && a != 0) {
a = 4*a;
b = 9*b - 8*c*c*c;
c = c;
}
}
return 0;
}