STMC is a statistical model checker that uses stratified or antithetic sampling techniques to reduce sample variance and hence required number of samples to make a statistical decision. It uses PRISM for loading probabilistic models and their simulation. The simulation engine is improved by STMC to make stratified and antithetic sampling possible. Please visit the Tool Page for a short introduction on stratified and antithetic sampling techniques, a list of related publications, and our benchmarks. Here we explain how to install and run benchmarks as well as examples.
Note: The following steps are tested on MacOS and Ubuntu.
-
Install Java (version 11 or higher) and set the
JAVA_HOME
environment variable to the installation folder. After this step, entering${JAVA_HOME}/bin/java -version
on terminal should successfully print the current java version.For example:
~$ ${JAVA_HOME}/bin/java -version java version "11.0.2" 2019-01-15 LTS Java(TM) SE Runtime Environment 18.9 (build 11.0.2+9-LTS) Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.2+9-LTS, mixed mode) ~$
-
Install PRISM (version 4.5) and set the
PRISM_HOME
environment variable to the installation folder. After this step, entering${PRISM_HOME}/bin/prism -version
on terminal should successfully print the current version of PRISM.For example:
~$ ${PRISM_HOME}/bin/prism -version PRISM version 4.5 ~$
This repository already contains the binary version. It only has Java bytecode which means no compilation is required to run the examples or benchmarks. However, if one wishes to change the code then they must carry out the compilation step as well.
Note: If you want to compile the source code, you are expected to have some experience working with IDEs and Java. Furthermore, most of STMC is written in Scala. So you need to know a little bit about this language as well.
We use IntelliJ IDEA (Community Edition) for our project. Follow the next steps to compile and run the source code:
-
Clone the source code on your local computer. You can do this by executing
git clone https://github.com/nima-roohi/STMC
in your terminal. -
Install the IDE and open/import STMC project folder in it.
-
Make sure your JDK is set properly (version 11 or above).
-
Make sure your Scala library is set property. If don't have it already, IntelliJ can download it for you. It also has a great plugin for coding in Scala which you should install as well.
-
Change whatever you like in the source code.
-
Build the project. This can be done, for example, by selecting
Build Project
from theBuild
menu. -
Rebuild the
stmc
artifact. This can be done, for example, by selectingBuild Artifacts...
and thenstmc > rebuild
from theBuild
menu. After this step, a Jar file calledstmc.jar
will be overwritten in./out/artifacts/stmc
. -
If you don't want to rebuild the artifact and just want to run the tool within the IDE, so that you can debug your code, instead of the previous step, run
src/edu/stmc/Main.scala
file by, for example, right-clicking on the file in the Navigation Pane and selectingRun 'Main.main()'
.Since STMC uses PRISM and since PRISM uses native libraries, our first attempt to run the code will most likely end up with
UnsatisfiedLinkError
. However, we now have a lunch configuration that we edit, by for example selectingEdit Configurations...
from theRun
menu, to fix this problem. In the following steps, make sure to replace/opt/prism-4.5
with the folder you installed PRISM in.- Enter
-Djava.library.path=/opt/prism-4.5/lib
forVM options
. - If you are on Linux, enter
LD_LIBRARY_PATH=/opt/prism-4.5/lib
forEnvironment variables
. - If you are on Mac, enter
DYLD_LIBRARY_PATH=/opt/prism-4.5/lib
forEnvironment variables
.
We are now ready to run the source code, which is already explained at the beginning of this step.
- Enter
Running the benchmarks is fairly straightforward.
Open a terminal and enter a folder that you can write into.
For the rest of this section, we assume you are in your home folder and use ~
to denote that folder.
Follow the next steps:
-
Clone the source code on your local computer (if you don't have
git
, you can download the source code using your browser as well).~$ git clone https://github.com/nima-roohi/STMC Cloning into 'STMC'... remote: Enumerating objects: 118, done. remote: Counting objects: 100% (118/118), done. remote: Compressing objects: 100% (71/71), done. remote: Total 2853 (delta 61), reused 88 (delta 36), pack-reused 2735 Receiving objects: 100% (2853/2853), 33.16 MiB | 7.33 MiB/s, done. Resolving deltas: 100% (1358/1358), done. ~$
-
Enter STMC folder.
~$ cd ./STMC/ ~/STMC$
-
Look at list of available examples and select one. For example, we choose
brp
.~/STMC$ ls ./examples/ brp crowds egl ~/STMC$
-
Run the benchmark.
~/STMC$ ./examples/brp/run.sh
This runs 68 statistical tests and attempts to run 20 symbolic tests (some of the symbolic ones might not survive the state space explosion). Furthermore, each of the statistical tests will be repeated 20 times, so we can gather average times and number of samples. Therefore, be ready to give it quite a few hours before it finishes.
You can reduce this time by changing all occurrences of
-mt 1
in file./examples/brp/run.sh
by-mt 4
or-mt
. The first option instructs STMC to use at most 4 processors for repeating statistical tests. The second option causes STMC to use all the available processes. Note that these are processes and not threads. Therefore, there will be slightly more overhead.When there are more than one processes, the synchronization between them is carried out through sockets. It is assumed port number
56437
is free. As a consequence, if you use more than one process (ie. change-mt 1
) you cannot run multiple benchmarks at the same time. The solution is to assign environment variableSTMC_PORT
to a free port of your choice. You should also use this step when56437
is taken by some other processes and you want to have multi-processes feature anyway. Failure to set the port properly when there are multiple processes involved, only causes STMC not to find statistical info about multiple runs of a statistical test.
In this section we explain how to run a single example and different options/switches involved in it.
There are three steps. The first two are exactly same as the first two steps in
Running the Benchmarks section
(clone the code from its repository and enter into STMC folder).
The last step is running the tool which is achieved by entering command
./stmc.sh <options>
in terminal.
We next explain STMC options and give a few examples for them.
-help
: Print the list of switches in both STMC and PRISM with a short description for each of them.<model-file>
: There is no switch for model file. Just enter the path to it. For example,./examples/brp/brp.pm
.-pf <property>
: Specifies the property that should be verified. For example,-pf 'P<0.39[F<100s=3]'
. STMC supports any property that PRISM can evaluate on a single path using its simulation engine.-stmc
: Enables STMC tool. Without this option, everything will be passed directly to PRISM, pretty much like STMC was not there in the first place.-sim
: Enables statistical verification. Whenever-stmc
is given,-sim
must be given as well. However, when-stmc
is not present,-sim
is optional (statistical vs. symbolic verification).-delta <value>
: Specifies half of the width of indifference region.-alpha <value>
: Specifies Type I error probability (the probability of incorrectly rejecting the null hypothesis).-beta <value>
: Specifies Type II error probability (the probability of incorrectly not rejecting the null hypothesis).-gamma <value>
: Specifies Type III error probability (the probability of incorrectly calling it too close to make a decision). As in PRISM, not all options are used by every algorithm. Please look at Scala documentation for classHypTestSPRTTernary
(can be found indocs-scala
folder) for further explanation of this parameter.-min_iter <integer>
: Minimum number of iterations before making a decision. Note that we define iteration independently of strata-size. For example, if strata size is 4096 then every iteration takes exactly 4096 samples.-strata_size <list>
: Specifies size of strata. It is a comma separated list of positive integers. For example,4,4,4,4,4,4
specifies strata-size 4 for 6 consecutive steps (4096 total), and4096
specifies strata-size 4096 for every single step.-smp_method
: Specifies the sampling method. Possible values are:independent
,antithetic
, andstratified
.-hyp_test_method
: Specifies the hypothesis testing method.
Possible values are:SPRT
: Sequential Probability Ratio Test. This algorithm is also implemented in PRISM and in our experience have a very similar performance to our implementation. We use our implementation for the next option.TSPRT
: Ternary SPRT. SPRT assumes that the actual probability is not within thedelta
-neighborhood of the input threshold. If this assumption is not satisfied then the algorithm does not guarantee any error probability. Ternary SPRT solves this problem by introducing a third possible answer:TOO_CLOSE
. Note that PRISM requires that result of a test to be either a boolean value or an integer. Therefore, whenever this option is used,-1
means false,1
means, and0
means actual probability and input threshold are too close to make a call.
Please look at Scala documentation for classHypTestSPRTTernary
(can be found indocs-scala
folder) for further explanation of this algorithm and a reference paper.GLRT
: General Likelihood Ratio Test. Please look at Scala documentation for classHypTestGLRT
(can be found indocs-scala
folder) for further explanation of this algorithm and a reference paper.SSPRT
: Stratified SPRT. This is the main method for both stratification and antithetic sampling.
-repeat <integer>
(experimental): Specifies number of times the test should be repeated. This is useful in the case of evaluating a statistical algorithm experimentally.-mt <integer>
(experimental - argument is optional): Maximum number of processes to use for repeating the experiment. If no argument is given then the number of available processes will be used as a default value.
Suppose we would like to statistically verify the model specified in
file ./examples/brp/brp.pm
against temporal property 'P<0.6[F<100s=3]'
(the intuitive meaning of this property is irrelevant to our discussion).
Below we give different examples of how this can be done using STMC.
Note that our model has two parameters that should be initialized before it can be simulated.
We use PRISM's switch -const
for that purpose.
-
Use stratification with strata-size
16
. Type I and Type II error probabilities are0.05
, indifference region is0.02
, and minimum number of iterations is10
../stmc.sh ./examples/brp/brp.pm -const MAX=256 -const N=65536 -pf 'P<0.6[F<100s=3]' -stmc -sim \ -alpha 0.05 -beta 0.05 -delta 0.01 -smp_method stratified -hyp_test_method SSPRT -strata_size 16 \ -min_iter 10
-
Same as the previous example, except that
16
strata should be divided into two steps each of size4
../stmc.sh ./examples/brp/brp.pm -const MAX=256 -const N=65536 -pf 'P<0.6[F<100s=3]' -stmc -sim \ -alpha 0.05 -beta 0.05 -delta 0.01 -smp_method stratified -hyp_test_method SSPRT -strata_size 4,4 \ -min_iter 10
-
Use antithetic sampling. Type I and Type II error probabilities are
0.05
, indifference region is0.02
, and minimum number of iterations is10
../stmc.sh ./examples/brp/brp.pm -const MAX=256 -const N=65536 -pf 'P<0.6[F<100s=3]' -stmc -sim \ -alpha 0.05 -beta 0.05 -delta 0.01 -smp_method antithetic -hyp_test_method SSPRT -min_iter 10
-
Use independent sampling with GLRT. Type I and Type II error probabilities are
0.05
, and minimum number of iterations is10
../stmc.sh ./examples/brp/brp.pm -const MAX=256 -const N=65536 -pf 'P<0.6[F<100s=3]' -stmc -sim \ -alpha 0.05 -beta 0.05 -delta 0.01 -smp_method independent -hyp_test_method GLRT -min_iter 10
-
Use stratified sampling with GLRT. Type I and Type II error probabilities are
0.05
, strata-size is2,4
, and minimum number of iterations is10
../stmc.sh ./examples/brp/brp.pm -const MAX=256 -const N=65536 -pf 'P<0.6[F<100s=3]' -stmc -sim \ -alpha 0.05 -beta 0.05 -delta 0.01 -smp_method stratified -hyp_test_method SSPRT -strata_size 2,4 \ -min_iter 10
-
Use independent sampling with TernarySPRT. Type I and Type II error probabilities are
0.05
, and Type III error probabilities is0.02
../stmc.sh ./examples/brp/brp.pm -const MAX=256 -const N=65536 -pf 'P<0.6[F<100s=3]' -stmc -sim \ -alpha 0.05 -beta 0.05 -gamma 0.02 -delta 0.01 -smp_method independent -hyp_test_method TSPRT
We have estimated that the actual probability in this example is
0.383213843614607
. You can use this number and smaller values to see all possible non-boolean outputs that are generated by TernarySPRT. -
Repeat the first example
10
times../stmc.sh ./examples/brp/brp.pm -const MAX=256 -const N=65536 -pf 'P<0.6[F<100s=3]' -stmc -sim \ -alpha 0.05 -beta 0.05 -delta 0.01 -smp_method stratified -hyp_test_method SSPRT -strata_size 16 \ -min_iter 10 -repeat 10
-
Repeat the first example
10
times using2
processes../stmc.sh ./examples/brp/brp.pm -const MAX=256 -const N=65536 -pf 'P<0.6[F<100s=3]' -stmc -sim \ -alpha 0.05 -beta 0.05 -delta 0.01 -smp_method stratified -hyp_test_method SSPRT -strata_size 16 \ -min_iter 10 -repeat 10 -mt 2
-
Repeat the first example
10
times using as many processes as available../stmc.sh ./examples/brp/brp.pm -const MAX=256 -const N=65536 -pf 'P<0.6[F<100s=3]' -stmc -sim \ -alpha 0.05 -beta 0.05 -delta 0.01 -smp_method stratified -hyp_test_method SSPRT -strata_size 16 \ -min_iter 10 -repeat 10 -mt