Skip to content

Commit 1fe50f4

Browse files
committed
Documentation: updates goto-symex/README.md
Specifically, this commit modifies goto-symex/README.md by elaborating on the roles played by symex_target_equationt and symex_targett.
1 parent dbd6988 commit 1fe50f4

File tree

1 file changed

+96
-32
lines changed

1 file changed

+96
-32
lines changed

src/goto-symex/README.md

Lines changed: 96 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,22 @@ when analysis is incomplete. The symbolic execution includes constant
1515
folding so loops that have a constant number of iterations will be
1616
handled completely (assuming the unwinding limit is sufficient).
1717

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.
2332

33+
---
2434
\section symbolic-execution Symbolic Execution
2535

2636
In the \ref goto-symex directory.
@@ -95,47 +105,80 @@ execution run does not add any paths to the workqueue but rather merges
95105
all the paths together, so the additional path-exploration loop is
96106
skipped over.
97107

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+
* \ref symex_targett
113+
* \ref 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+
indexed (renamed) through the addition of a _suffix_.
123+
124+
There are three “levels” of indexing:
125+
126+
**Level 2 (L2):** variables are indexed every time they are
127+
encountered in a function.
128+
129+
**Level 1 (L1):** variables are indexed every time the functions that
130+
contain those variables are called.
131+
132+
**Level 0 (L0):** variables are indexed every time a new thread
133+
containing those variables are spawned.
134+
135+
We can inspect the indexed variable names with the **--show-vcc** or
136+
**--program-only** flags. Variables in SSA form are printed in the
137+
following format: `%%s!%%d@%%d#%%d`. Where the string field is the
138+
variable name, and the numbers after the !, @, and # are the L0, L1,
139+
and L2 suffixes respectively.
140+
141+
> Note: **--program-only** prints all the SSA steps in-order. In
142+
> contrast, **--show-vcc** will for each assertion print the SSA steps
143+
> (assumes, assignments and constraints only) that synthetically
144+
> precede the assertion. In the presence of multiple threads it will
145+
> also print SSA steps that succeed the assertion.
146+
147+
\subsection L1-L2 Level 1 and level 2 indexing
148+
149+
The following examples illustrate Level 1 and 2 indexing.
112150

113151
$ cat l1.c
114-
int main() {
152+
int main()
153+
{
115154
int x=7;
116155
x=8;
117156
assert(0);
118157
}
158+
119159
$ cbmc --show-vcc l1.c
120160
...
121161
{-12} x!0@1#2 == 7
122162
{-13} x!0@1#3 == 8
123163

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).
164+
That is, the L0 names for both x's are 0; the L1 names for both x's
165+
are 1; but each occurrence of x within main() gets a fresh L2 suffix
166+
(2 and 3, respectively).
127167

128168
$ cat l2.c
129-
void foo(){
169+
void foo()
170+
{
130171
int x=7;
131172
x=8;
132173
x=9;
133174
}
134-
int main(){
175+
int main()
176+
{
135177
foo();
136178
foo();
137179
assert(0);
138180
}
181+
139182
$ cbmc --show-vcc l2.c
140183
...
141184
{-12} x!0@1#2 == 7
@@ -146,21 +189,42 @@ respectively).
146189
{-17} x!0@2#4 == 9
147190

148191
That is, every time we enter function foo, the L1 counter of x is
149-
incremented (from 1 to 2) and the L0 counter is reset (back to 2, after
150-
having been incremented up to 4). The L0 counter then increases every
151-
time we access x as we walk through the function.
192+
incremented (from 1 to 2) and the L2 counter is reset (back to 2,
193+
after having been incremented up to 4). The L2 counter then increases
194+
every time we access x as we walk through the function.
195+
196+
\subsection L0 Level 0 indexing (threads only)
197+
198+
TODO: describe and give a concrete example
199+
200+
\subsection PL Relevant Primary Literature
201+
202+
Thread indexing is based on the following paper:
203+
204+
> Lee, J., Midkiff, S.P. and Padua, D.A., 1997, August. Concurrent
205+
> static single assignment form and constant propagation for
206+
> explicitly parallel programs. In International Workshop on Languages
207+
> and Compilers for Parallel Computing (pp. 114-130). Springer,
208+
> Berlin, Heidelberg.
209+
210+
Seminal paper on SSA:
211+
212+
> Rosen, B.K., Wegman, M.N. and Zadeck, F.K., 1988, January. Global
213+
> value numbers and redundant computations. In Proceedings of the 15th
214+
> ACM SIGPLAN-SIGACT symposium on Principles of programming languages
215+
> (pp. 12-27). ACM.
152216
153217
---
154218
\section counter-example-production Counter Example Production
155219

156220
In the \ref goto-symex directory.
157221

158222
**Key classes:**
159-
* symex_target_equationt
160-
* prop_convt
223+
* \ref symex_target_equationt
224+
* \ref prop_convt
161225
* \ref bmct
162-
* fault_localizationt
163-
* counterexample_beautificationt
226+
* \ref fault_localizationt
227+
* \ref counterexample_beautificationt
164228

165229
\dot
166230
digraph G {

0 commit comments

Comments
 (0)