-
Notifications
You must be signed in to change notification settings - Fork 36
Expand file tree
/
Copy pathCorrectLoopCondition.java
More file actions
145 lines (122 loc) · 3.61 KB
/
Copy pathCorrectLoopCondition.java
File metadata and controls
145 lines (122 loc) · 3.61 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
package testSuite;
import liquidjava.specification.Refinement;
import liquidjava.specification.StateRefinement;
import liquidjava.specification.StateSet;
@SuppressWarnings("unused")
@StateSet({"open", "closed"})
public class CorrectLoopCondition {
int field;
@StateRefinement(to = "open(this)")
CorrectLoopCondition() {}
@StateRefinement(from = "open(this)", to = "closed(this)")
void close() {}
@StateRefinement(from = "open(this)")
void use() {}
@StateRefinement(to = "return ? open(this) : closed(this)")
boolean isOpen() {
return true;
}
void setFieldNegative() {
field = -1;
}
@Refinement("_ >= -1")
static int read() {
return -1;
}
static void write(@Refinement("_ > 0") int n) {}
static void open(@Refinement("_ >= 0 && _ <= 65535") int port) {}
static void lessThanTen(@Refinement("_ < 10") int n) {}
// the condition holds in the body, and again after each re-assignment once it is re-checked
static void readLoop() {
int n = read();
while (n > 0) {
write(n);
n = read();
}
}
// the loop variable keeps its declared refinement across iterations; the condition gives the upper bound
static void scanFrom(int start) {
if (start <= 0) {
return;
}
for (@Refinement("_ > 0") int i = start; i < 65535; i++) {
open(i);
}
}
// the update runs after the body: the body sees i < 10, not i + 1
static void updateAfterBody() {
for (@Refinement("_ >= 0") int i = 0; i < 10; i++) {
lessThanTen(i);
}
}
// the condition is assumed on a variable the body does not modify
static void unmodifiedVariable(int limit) {
int count = 0;
while (limit > 0 && count < 10) {
write(limit);
count = count + 1;
}
}
// conditions of nested loops hold together in the inner body
static void nestedLoops(int a, int b) {
while (a > 0) {
while (b > 0) {
write(a);
write(b);
b = read();
}
a = read();
}
}
// an if (...) break inside the body is a path condition for the rest of the body
static void breakInBody() {
while (true) {
int n = read();
if (n <= 0) {
break;
}
write(n);
}
}
// the declared refinement of a variable assigned in the loop holds after it
static void valueAfterLoop(boolean c) {
@Refinement("_ > 0") int n = 1;
while (c) {
n = 2;
}
write(n);
}
// a continue in the body, with an update that needs no fact from the body
static void continueInFor(int p) {
int n = p;
for (int i = 0; i < 10; i++) {
if (n <= 0) {
continue;
}
write(n);
}
}
// the condition on a field holds in the body
void fieldCondition() {
while (field > 0) {
write(field);
field = field - 1;
}
}
// methods that keep the state of r can be called in the loop
static void stateKeptInLoop(int k) {
CorrectLoopCondition r = new CorrectLoopCondition();
while (k > 0) {
r.use();
k = k - 1;
}
r.close();
}
// the condition checks the state of r on every iteration
static void stateCheckedByCondition(CorrectLoopCondition r) {
while (r.isOpen()) {
r.use();
r.close();
}
}
}