This is a short overview of the terminology we use in this class. We know that it is somewhat inconsistent between the lectures, but we hope to clean it up over time.
Before we get started, we need to introduce some basic notation. We use capital letters and to indicate sets, and small letters and to be elements of those sets.
We use small and to indicate programs.
A Transition system is a triplet where is the set of program states, is the transition relation (defined by the single step semantics) and are possible initial states.
A trace is now the sequences of states that a program traverse during execution.
The traces of a program is a sequence of states for . We use to refer to individual traces. We sometimes index the traces like so , where is the initial state.
We define the semantics a program to be the set of traces which we can generate from the transition system. This is also known as the Maximal Trace Semantics.
Using the trace semantics, we can now talk about properties of programs. When the property is generic we use capital letters and , but when we are talking about a concrete property we use okay or error.
We differentiate between two kinds of properties, may-properties, and must-properties. A may property is true for one trace, while a must property is true for all traces.
MayProperty
A may-property is true for at least one trace in the program:
MustProperty
A must-property is true for all traces in the program:
Interestingly, if we negate the property of a may
analysis we get a must
analysis and visa-versa.
Sometimes we talk about properties which are bounded by some depth . In this world we only look at traces shorter than states.
In this world, we can also talk about may
and must
properties and . Which claims that is true for one or all traces smaller than size in .
Program analysis is an automatic procedure that attempts to determine a property about a program. Since an analysis is tailor-made to predict a specific may
property , we write it like so , and we write a must
property as .
Since program analysis is undecidable, it is in general impossible for an analysis to perfectly match the true property of the code; therefore, we approximate it.
A common confusion in program analysis is that static analyses accept or reject properties over programs, where dynamic analyses accept and reject properties over traces.
This has consequences over what they consider sound and complete.
A sound analysis is never wrong:
In a sound system, every proved fact is a true fact. Any property found by a sound analysis is true.
A static analysis focuses on properties over all traces: must
properties. So when we say a static analysis is sound, it is must
sound. A dynamic analysis focuses on properties over some traces, may
properties, so when we say it is sound it is may
sound.
When we use the notation or you can assume that they imply and respectively.
If a may
analysis finds that a program raises a null-pointer exception for some trace, then there exist a trace that raises a null-pointer exception.
If a must
analysis finds that the program must raise a null-pointer exception, then the program will raise a null-pointer exception on all traces.
The other side of the coin is completeness. A complete analysis never misses a property. To clearly differentiate the sound analyses from the complete ones, we use not-must
and not-may
instead, to indicate that the analysis tries to under approximate a property.
In a complete system, every true fact can be proved. All false properties can be rejected by a complete analysis.
When we use the notation or you can assume that they are implied by and respectively.
If a program raise a null-pointer exception for any trace, a not-may
analysis will find the that the program can raise a null-pointer exception on some trace.
If a program raise a null-pointer exception on all traces (must), a not-must
analysis will find the program raises null-pointer exception on all traces.
An analysis can be sound or complete, but never both.
Recall that it is generally true that a may property is an inverted must property:
This is also the case for program analyses, any complete may
analysis can be made into a sound must
analysis over the negated property:
We can see this quite clearly. If take the completeness requirement, and flip the implication by negating on both sides:
Now by using the rule above we see that implies , which means that is a sound must analysis.
It is common to use the terminology of false/true positives/negatives, when referring to a classifier. However, this is confusing when referring to program analysis as it unclear if we are referring to classification over programs (must analyses and not-may analyses) or classification over traces (may analyses and not-must analyses).
To clear up this confusion, we use warnings
to refer to specific bugs reported in the program, essentially classification over traces.
A sound static analysis might produce false warnings, where a sound dynamic analysis will never produce false warnings.
Like with our semantics we can bound our analyses, for example we can write , and .
However, generally a bounded must analysis is not a must analysis,
and a bounded not-may analysis is not a not-may analysis: