@@ -15,12 +15,22 @@ when analysis is incomplete. The symbolic execution includes constant
15
15
folding so loops that have a constant number of iterations will be
16
16
handled completely (assuming the unwinding limit is sufficient).
17
17
18
- The output of the symbolic execution is a system of equations; an object
19
- containing a list of ` symex_target_elements ` , each of which are
20
- equalities between ` expr ` expressions. See ` symex_target_equation.h ` .
21
- The output is in static, single assignment (SSA) form, which is * not*
22
- the case for goto-programs.
18
+ The output of symbolic execution is a system of equations; an object
19
+ of type ` symex_target_equationt ` , containing a list of
20
+ ` symex_target_equationt::SSA_stept ` , each of which are equalities
21
+ between ` exprt ` expressions. This list is constructed incrementally as
22
+ the symbolic execution engine walks through the goto-program using the
23
+ ` symex_targett ` interface. This interface (implemented by
24
+ ` symex_target_equationt ` ) exposes functions that append SSA steps into
25
+ the aforementioned list while transforming expressions into
26
+ Static Single Assignment (SSA) form. For more details on this process
27
+ see ` symex_target_equation.h ` , for an overview of SSA see
28
+ \ref static-single-assignment.
29
+
30
+ At a later stage, BMC will convert the generated SSA steps into an
31
+ equation that can be passed to the solver.
23
32
33
+ ---
24
34
\section symbolic-execution Symbolic Execution
25
35
26
36
In the \ref goto-symex directory.
@@ -95,47 +105,73 @@ execution run does not add any paths to the workqueue but rather merges
95
105
all the paths together, so the additional path-exploration loop is
96
106
skipped over.
97
107
98
- \subsection ssa-renaming SSA renaming levels
99
-
100
- In goto-programs, variable names get a prefix to indicate their scope
101
- (like ` main::1::%foo ` or whatever). At symbolic execution level, variables
102
- also get a _ suffix_ because we’re doing single-static assignment. There
103
- are three “levels” of renaming. At Level 2, variables are renamed every
104
- time they are encountered in a function. At Level 1, variables are
105
- renamed every time the functions that contain those variables are
106
- called. At Level 0, variables are renamed every time a new thread
107
- containing those variables are spawned. We can inspect the renamed
108
- variable names with the –show-vcc flag, which prints a string with the
109
- following format: ` %%s!%%d@%%d#%%d ` . The string field is the variable name,
110
- and the numbers after the !, @, and # are the L0, L1, and L2 suffixes
111
- respectively. The following examples illustrate Level 1 and 2 renaming:
108
+ ---
109
+ \section static-single-assignment Static Single Assignment (SSA) Form
110
+
111
+ ** Key classes:**
112
+ * symex_targett
113
+ * symex_target_equationt
114
+
115
+ * Static Single Assignment (SSA)* form is an intermediate
116
+ representation that satisfies the following properties:
117
+
118
+ 1 . Every variable is * assigned exactly once* .
119
+ 2 . Every variable must be * defined* before use.
120
+
121
+ In-order to convert a goto-program to SSA form all variables are
122
+ versioned (renamed) through the addition of a _ suffix_ .
123
+
124
+ There are three “levels” of versioning:
125
+
126
+ ** Level 2 (L2):** variables are versioned every time they are encountered
127
+ in a function.
128
+
129
+ ** Level 1 (L1):** variables are versioned every time the functions that
130
+ contain those variables are called.
131
+
132
+ ** Level 0 (L0):** variables are versioned every time a new thread
133
+ containing those variables are spawned.
134
+
135
+ We can inspect the versioned variable names with the ** –show-vcc** flag,
136
+ this prints a string with the following format: ` %%s!%%d@%%d#%%d ` .
137
+ Where the string field is the variable name, and the numbers after
138
+ the !, @, and # are the L0, L1, and L2 suffixes respectively.
139
+
140
+ \subsection L1-L2 Level 1 and level 2 versioning
141
+
142
+ The following examples illustrate Level 1 and 2 versioning.
112
143
113
144
$ cat l1.c
114
- int main() {
145
+ int main()
146
+ {
115
147
int x=7;
116
148
x=8;
117
149
assert(0);
118
150
}
151
+
119
152
$ cbmc --show-vcc l1.c
120
153
...
121
154
{-12} x!0@1#2 == 7
122
155
{-13} x!0@1#3 == 8
123
156
124
- That is, the L0 names for both xs are 0; the L1 names for both xs are 1;
125
- but each occurrence of x within main() gets a fresh L2 suffix (2 and 3,
126
- respectively).
157
+ That is, the L0 names for both x's are 0; the L1 names for both x's are
158
+ 1; but each occurrence of x within main() gets a fresh L2 suffix (2
159
+ and 3, respectively).
127
160
128
161
$ cat l2.c
129
- void foo(){
162
+ void foo()
163
+ {
130
164
int x=7;
131
165
x=8;
132
166
x=9;
133
167
}
134
- int main(){
168
+ int main()
169
+ {
135
170
foo();
136
171
foo();
137
172
assert(0);
138
173
}
174
+
139
175
$ cbmc --show-vcc l2.c
140
176
...
141
177
{-12} x!0@1#2 == 7
@@ -150,6 +186,10 @@ incremented (from 1 to 2) and the L0 counter is reset (back to 2, after
150
186
having been incremented up to 4). The L0 counter then increases every
151
187
time we access x as we walk through the function.
152
188
189
+ \subsection L0 Level 0 versioning
190
+
191
+ TODO
192
+
153
193
---
154
194
\section counter-example-production Counter Example Production
155
195
0 commit comments