Skip to content
Snippets Groups Projects
Commit 83297177 authored by Jaime Arias's avatar Jaime Arias Committed by Jaime Arias
Browse files

improve CLI

parent 554f8c77
Branches main
No related tags found
1 merge request!4Improve the CLI
Pipeline #4845 passed with stage
in 1 minute and 25 seconds
......@@ -6,5 +6,8 @@ FROM mcr.microsoft.com/vscode/devcontainers/cpp:0-${VARIANT}
# [Optional] Uncomment this section to install additional packages.
RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \
&& apt-get -y install --no-install-recommends cmake bison flex \
openmpi-bin libopenmpi-dev
&& apt-get -y install --no-install-recommends wget cmake bison flex \
openmpi-bin libopenmpi-dev && \
wget http://www.lrde.epita.fr/dload/spot/spot-2.10.4.tar.gz && \
tar xzf spot-2.10.4.tar.gz && cd spot-2.10.4 && \
./configure --disable-doxygen --disable-python && make && make install
......@@ -172,5 +172,6 @@ crashlytics-build.properties
fabric.properties
assets
*.dot
# End of https://www.gitignore.io/api/c++,cmake
......@@ -17,9 +17,8 @@ build:
- echo 'deb http://www.lrde.epita.fr/repo/debian/ stable/' >> /etc/apt/sources.list
- apt-get update && apt-get install -y spot libspot-dev
script:
- mkdir build && cd build
- cmake ..
- cmake --build . --target install
- cmake -S . -B build
- cmake --build build --target install
artifacts:
paths:
- assets/pmc-sog
......
......@@ -2,100 +2,168 @@
(P)arallel (M)odel (C)hecking using the (S)ymbolic (O)bservation (G)raph.
A [Symbolic Observation Graph](https://www.researchgate.net/profile/Kais_Klai/publication/48445044_Design_and_Evaluation_of_a_Symbolic_and_Abstraction-Based_Model_Checker/links/00463514319a181966000000.pdf) software tool has been implemented in C/C++.
The user can choose between sequential or parallel construction.
The [BuDDy](http://buddy.sourceforge.net/manual/main.html) BDD package and [Sylvan](https://trolando.github.io/sylvan/) package are exploited in order to represent aggregates compactly.
BuDDy used for sequential version and Sylvan for both sequential and parallel construction.
It is necessary to install [Spot](https://spot.lrde.epita.fr/install.html).
A [Symbolic Observation Graph](https://www.researchgate.net/profile/Kais_Klai/publication/48445044_Design_and_Evaluation_of_a_Symbolic_and_Abstraction-Based_Model_Checker/links/00463514319a181966000000.pdf)
(SOG) software tool has been implemented in C/C++. The user can choose between
sequential or parallel construction.
## Description
This repository hosts the experiments and results for the Hybrid (MPI/pthreads) approach for the SOG construction and provides a short guide on how to install the tools and reproduce the results.
This repository hosts the code source for the Hybrid (MPI/pthreads) approach for
the SOG construction and its use for model-checking.
* **MPI:** The Message Passing Interface ([OpenMPI](https://www.open-mpi.org/) implementation). The goal of the MPI is to establish a portable, efficient, and flexible standard for message passing between processess (nodes).
* **MPI:** The Message Passing Interface ([OpenMPI](https://www.open-mpi.org/)
implementation). The goal of the MPI is to establish a portable, efficient, and
flexible standard for message passing between processess (nodes).
* **Pthread:** POSIX thread library. Mutexes (Pthread lock functionality) are used to prevent data inconsistencies due to race conditions.
* **Pthread:** POSIX thread library. Mutexes (Pthread lock functionality) are
used to prevent data inconsistencies due to race conditions.
## Dependencies
- [Cmake](https://cmake.org/)
The following dependencies are necessary to build the tool.
- [Bison](https://www.gnu.org/software/bison/)
- [Cmake](https://cmake.org/)
- [Flex](https://github.com/westes/flex)
- [OpenMPI](https://www.open-mpi.org/) development libraries
- [OpenSSL](https://www.openssl.org/) development libraries
- [GMP](https://gmplib.org/) development libraries
- [Spot](https://spot.lrde.epita.fr/install.html) library
## Building
## Build
The steps to build the tool are the following:
- `git clone --recursive https://depot.lipn.univ-paris13.fr/PMC-SOG/mc-sog.git`
- `cd mc-sog && mkdir build && cd build`
- `cd mc-sog`
- `cmake -S . -B build`
- `cmake --build build --target install`
The compiled binary `pmc-sog` can be found in the folder `assets`.
## CLI
```
PMC-SOG : Parallel Model Checking tool based on Symbolic Observation Graphs
Usage: ./assets/pmc-sog [OPTIONS]
Options:
-h,--help Print this help message and exit
--n Integer:POSITIVE Number of threads to be created (default: 1)
--net Path:FILE REQUIRED Petri net file
--ltl Path:FILE REQUIRED LTL property file
--thread TEXT:{posix,c++} Thread library (default: c++)
--por,--no-por{false} Apply partial order reductions (default: false)
--progressive,--no-progressive{false} Excludes: --explicit
Use a progressive construction of the SOG (default: false)
Explicit MC:
--explicit Excludes: --progressive --emptiness-check
Run explicit model-checking
--lace,--no-lace{false} Needs: --explicit
Use the work-stealing framework Lace (default: false)
--canonization,--no-canonization{false} Needs: --explicit
Apply canonization to the SOG (default: false)
--only-sog Needs: --explicit
Only builds the SOG
On-the-fly MC:
--emptiness-check TEXT Excludes: --explicit
Spot emptiness-check algorithm
Print:
--dot-sog Needs: --explicit Save the SOG in a dot file
--dot-formula Save the automata of the negated formula in a dot file
--counter-example Needs: --explicit
Save the counter example in a dot file
```
The emptiness-check algorithms are provided by spot. For more information,
please see https://spot.lrde.epita.fr/doxygen/group__emptiness__check.html.
Here, some of examples:
- `cmake ..`
* Cou99
+ shy
+ poprem
+ group
* GC04
* CVWY90
+ bsh : set the size of a hash-table
* SE05
+ bsh : set the size of a hash-table
* Tau03
* Tau03_opt
- `cmake --build .`
## Examples
### Multi-Core Model-Checking
## Testing
SOG building from an LTL formula (philo3.net example)
In the following example, the model `train12.net` is verified using the
multi-core on-the-fly model-checking (progressive) with 4 posix threads and no
partial order reduction (POR). The emptiness-check algorithm used is the
Couvreur's algorithm.
```
Multi-threading execution
mpirun -n 1 hybrid-sog arg1 arg2 arg3 arg4 [arg5]
arg1: specifies method of creating threads or/and specifies if modelchecking should be performed on the fly. It can be set with one of the following values:
* p : using pthread library
* pc : using pthread library and applying canonization on nodes
* otfP : perform modelchecking on the fly using pthread
* otfC : perform modelchecking on the fly using c++17 algorithms and a work-stealing approach for the construction of aggregates
* otfCPOR : same as otfC with POR
* otfPR : progressive construction of the SOG during model checking (c++17 posix threads)
arg2: specify the number of threads/workers to be created
arg3: specify the net to build its SOG
arg4: specify the LTL formula file
arg5: (Optional) select an algorithm for the emptiness check provided by spot, see https://spot.lrde.epita.fr/doxygen/group__emptiness__check.html
* Cou99
+ shy
+ poprem
+ group
* GC04
* CVWY90
+ bsh : set the size of a hash-table
* SE05
+ bsh : set the size of a hash-table
* Tau03
* Tau03_opt
Distributed execution
mpirun -n arg0 hybrid-sog arg1 arg 2 arg3 arg4
arg0 : specifies the number of processes must be >1
arg1: specifies whether modelchecking should be performed on the fly. It can be set with one of the following values:
* otf : Construction performing Model checking on the fly while trying to build whole SOG
* otfPOR : Same as otf with Partial Order Reduction
* otfPR : Construction performing Model checking on the fly. The construction of the SOG is performed progressively alongside Model checking
* otherwise : construction without Model checking
arg2: specifies the number of threads/workers to be created
arg3: specifies the net to build its SOG
arg4: specifies the LTL formula file
arg5: (Optional) select an algorithm for the emptiness check provided by spot, see https://spot.lrde.epita.fr/doxygen/group__emptiness__check>
* Cou99
+ shy
+ poprem
+ group
* GC04
* CVWY90
+ bsh : set the size of a hash-table
* SE05
+ bsh : set the size of a hash-table
* Tau03
* Tau03_opt
mpirun -n 1 ./pmc-sog \
--n 4 \
--net build/hybrid/models/train/train12.net \
--ltl build/hybrid/formulas/train/train12/train12-1.ltl.reduced \
--thread posix \
--no-por \
--progressive \
--emptiness-check "Cou99(poprem)"
```
In the following example, the model `train12.net` is verified using the explicit
multi-core model-checking with 4 posix threads and no partial order reduction
(POR). Moreover, the SOG is canonized and the lace framework is used. Finally,
the tool generates the `.dot` files of the SOG, the automaton of negated
formula, and a counter-example if the property is violated.
```
mpirun -n 1 ./pmc-sog \
--n 4 \
--net build/hybrid/models/train/train12.net \
--ltl build/hybrid/formulas/train/train12/train12-1.ltl.reduced \
--thread posix \
--no-por \
--explicit \
--lace \
--canonization \
--dot-sog \
--dot-formula \
--counter-example
```
### Hybrid Model-Checking
**Note:** To run the hybrid version, the minimum number of MPI processes `n` is 2.
In the following example, the model `train12.net` is verified using the hybrid
on-the-fly model-checking (progressive) with 2 processes, each process with 4
C++ threads and no partial order reduction (POR). The emptiness-check algorithm
used is the Couvreur's algorithm.
```
mpirun -n 2 ./pmc-sog \
--n 4 \
--net build/hybrid/models/train/train12.net \
--ltl build/hybrid/formulas/train/train12/train12-1.ltl.reduced \
--no-por \
--progressive \
--emptiness-check "Cou99(poprem)"
```
## Publications
1. [A Parallel Construction of the Symbolic Observation Graph: the Basis for Efficient Model Checking of Concurrent Systems 2017](https://www.researchgate.net/publication/315840512_A_Parallel_Construction_of_the_Symbolic_Observation_Graph_the_Basis_for_Efficient_Model_Checking_of_Concurrent_Systems)
2. [Parallel Symbolic Observation Graph 2017](https://ieeexplore.ieee.org/document/8367348)
......@@ -103,6 +171,3 @@ arg5: (Optional) select an algorithm for the emptiness check provided by spot, s
3. [Reducing Time and/or Memory Consumption of the SOG Construction in a Parallel Context](https://ieeexplore.ieee.org/abstract/document/8672359)
4. [Towards Parallel Verification of Concurrent Systems using the Symbolic Observation Graph](https://ieeexplore.ieee.org/abstract/document/8843636)
......@@ -7,6 +7,7 @@
#include <CLI11.hpp>
#include "LDDGraph.h"
#include <spot/kripke/kripke.hh>
#include "MCMultiCore/ModelCheckerCPPThread.h"
#include "MCMultiCore/ModelCheckerTh.h"
#include "MCMultiCore/ModelCheckThReq.h"
......@@ -39,7 +40,7 @@
using namespace std;
int n_tasks, task_id;
unsigned int nb_th; // used by the distributed model checker
unsigned int nb_th = 1; // used by the distributed model checker
struct Formula
{
......@@ -47,6 +48,21 @@ struct Formula
set<string> propositions;
};
/**
* Save a graph in a dot file
*
* @param graph Graph to be saved
* @param filename Output filename
* @param options Options to customized the print
*/
void saveGraph(spot::twa_graph_ptr graph, const string &filename, const char *options = nullptr)
{
fstream file;
file.open(filename.c_str(), fstream::out);
spot::print_dot(file, graph, options);
file.close();
}
/**
* Parse a file containing a LTL formula and return its negation
*
......@@ -104,14 +120,21 @@ Formula negateFormula(const string &fileName)
*
* @param f Formula to be converted
* @param bdd BDD structure
* @param save_dot Save the automaton of the negated formula in a dot file
* @return spot::twa_graph_ptr
*/
spot::twa_graph_ptr formula2Automaton(const spot::formula &f, spot::bdd_dict_ptr bdd)
spot::twa_graph_ptr formula2Automaton(const spot::formula &f, spot::bdd_dict_ptr bdd, bool save_dot = false)
{
cout << "\nBuilding automata for not(formula)\n";
spot::twa_graph_ptr af = spot::translator(bdd).run(f);
cout << "Formula automata built.\n"
<< endl;
cout << "Formula automata built." << endl;
// save the generated automaton in a dot file
if (save_dot)
{
saveGraph(af, "negated_formula.dot");
}
return af;
}
......@@ -123,9 +146,9 @@ spot::twa_graph_ptr formula2Automaton(const spot::formula &f, spot::bdd_dict_ptr
void displayCheckResult(bool res)
{
if (res)
cout << "Property is verified..." << endl;
cout << "\nProperty is verified..." << endl;
else
cout << "Property is violated..." << endl;
cout << "\nProperty is violated..." << endl;
}
/**
......@@ -139,40 +162,6 @@ void displayTime(auto startTime, auto finalTime)
cout << "Verification duration : " << std::chrono::duration_cast<std::chrono::milliseconds>(finalTime - startTime).count() << " milliseconds\n";
}
/**
* Checks if the options are valid to run the multi-core version
*
* @param nb_threads Number of threads
* @param method Method to build the threads
* @return bool
*/
bool isValidMultiCoreMCOption(int nb_threads, const string &method)
{
set<string> options = {"otfPR",
"otfC",
"otfP",
"otfCPOR"};
return (nb_threads == 1 && (options.find(method) != options.end()));
}
/**
* Checks if the options are valid to run the hybrid version
*
* @param nb_threads Number of threads
* @param method Method to build the distributed SOG
* @return bool
*/
bool isValidHybridMCOption(int nb_threads, const string &method)
{
set<string> options = {"otf",
"otfPR",
"otfPOR",
"otfPRPOR"};
return (nb_threads > 1 && (options.find(method) != options.end()));
}
/**
* Print information of the execution
*
......@@ -202,42 +191,88 @@ void displayToolInformation(const string &net, const string &formula, const stri
* Get the multi-core model-checker
*
* @param net Net to be verified
* @param method Multi-core implementation
* @param nb_th Number of threads
* @param thread_library Thread library
* @param progressive Flag for a progressive construction of the SOG
* @param por Flag for partial order reduction
* @return ModelCheckBaseMT*
*/
ModelCheckBaseMT *getMultiCoreMC(NewNet &net, const string &method, int nb_th)
ModelCheckBaseMT *getMultiCoreMC(NewNet &net, int nb_th, const string &thread_library, bool progressive, bool por)
{
ModelCheckBaseMT *mcl = nullptr;
// select the right model-checking algorithm
if (method == "otfP")
if (thread_library == "posix")
{
cout << "Multi-threaded algorithm based on Pthread library!" << endl;
mcl = new ModelCheckerTh(net, nb_th);
if (progressive)
{
cout << "Multi-threaded algorithm (progressive) based on PThread!" << endl;
mcl = new ModelCheckThReq(net, nb_th);
}
else
{
cout << "Multi-threaded algorithm based on Pthread library!" << endl;
mcl = new ModelCheckerTh(net, nb_th);
}
}
else if (method == "otfPR")
else if (thread_library == "c++")
{
cout << "Multi-threaded algorithm (progressive) based on PThread!" << endl;
mcl = new ModelCheckThReq(net, nb_th);
if (por)
{
cout << "Multi-threaded algorithm based on C++ Thread library with POR!" << endl;
mcl = new MCCPPThPor(net, nb_th);
}
else
{
cout << "Multi-threaded algorithm based on C++ Thread library!" << endl;
mcl = new ModelCheckerCPPThread(net, nb_th);
}
}
else if (method == "otfC")
else
{
cout << "Multi-threaded algorithm based on C++ Thread library!" << endl;
mcl = new ModelCheckerCPPThread(net, nb_th);
cout << thread_library << " is not a valid thread library for the multi-core version" << endl;
exit(-1);
}
else if (method == "otfCPOR")
return mcl;
}
/**
* Get the multi-core construction option of the SOG
*
* @param thread_library Thread library
* @param canonization Flag to apply canonization
* @param por Flag for partial order reduction
* @return int
*/
int getMultiCoreBuildOption(const string &thread_library, bool canonization, bool por)
{
if (thread_library == "posix")
{
cout << "Multi-threaded algorithm with POR!" << endl;
mcl = new MCCPPThPor(net, nb_th);
if (canonization)
{
cout << "Canonized construction with pthread library." << endl;
return 1;
}
else
{
if (por)
{
cout << "Partial Order Reduction with pthread library." << endl;
return 2;
}
else
{
cout << "Construction with pthread library." << endl;
return 0;
}
}
}
else
{
cout << method << " is not valid for the multi-core version" << endl;
cout << thread_library << " is not a valid threads library for the multi-core version" << endl;
exit(-1);
}
return mcl;
}
/**
......@@ -245,57 +280,63 @@ ModelCheckBaseMT *getMultiCoreMC(NewNet &net, const string &method, int nb_th)
*
* @param net Net to be verified
* @param method Hybrid implementation
* @param progressive Flag for a progressive construction of the SOG
* @param por Flag for partial order reduction
* @param communicator MPI communicator
* @return CommonSOG*
*/
CommonSOG *getHybridMC(NewNet &net, const string &method, MPI_Comm &communicator)
CommonSOG *getHybridMC(NewNet &net, const string &thread_library, bool progressive, bool por, MPI_Comm &communicator)
{
CommonSOG *DR;
if (method == "otf")
{
cout << " Normal construction..." << endl;
DR = new MCHybridSOG(net, communicator, false);
}
else if (method == "otfPOR")
{
cout << " Normal construction with POR" << endl;
DR = new MCHybridSOGPOR(net, communicator, false);
}
else if (method == "otfPR")
{
cout << " Progressive construction..." << endl;
DR = new MCHybridSOGReq(net, communicator, false);
}
else if (method == "otfPRPOR")
if (thread_library == "c++")
{
cout << " Progressive construction with POR..." << endl;
DR = new MCHybridSOGReqPOR(net, communicator, false);
if (progressive)
{
if (por)
{
cout << " Progressive construction with POR..." << endl;
DR = new MCHybridSOGReqPOR(net, communicator, false);
}
else
{
cout << " Progressive construction..." << endl;
DR = new MCHybridSOGReq(net, communicator, false);
}
}
else
{
if (por)
{
cout << " Normal construction with POR" << endl;
DR = new MCHybridSOGPOR(net, communicator, false);
}
else
{
cout << " Normal construction..." << endl;
DR = new MCHybridSOG(net, communicator, false);
}
}
}
else
{
cout << " " << method << " is not valid for the hybrid version" << endl;
exit(0);
cout << thread_library << " is not a valid thread library for the hybrid version" << endl;
exit(-1);
}
return DR;
}
/**
* Save a graph in a dot file
* Run the on-the-fly model-checking algorithm
*
* @param graph Graph to be saved
* @param filename Output filename
* @param options Options to customized the print
* @param algorithm Emptiness-check algorithm
* @param k Kripke structure of the SOG
* @param af Automata of the negated formula
* @return bool
*/
void saveGraph(spot::twa_graph_ptr graph, const string &filename, const char *options = nullptr)
{
fstream file;
file.open(filename.c_str(), fstream::out);
spot::print_dot(file, graph, options);
file.close();
}
void runOnTheFlyMC(const string &algorithm, auto k, spot::twa_graph_ptr af)
bool runOnTheFlyMC(const string &algorithm, auto k, spot::twa_graph_ptr af)
{
bool res = false;
std::chrono::steady_clock::time_point startTime, finalTime;
......@@ -337,6 +378,8 @@ void runOnTheFlyMC(const string &algorithm, auto k, spot::twa_graph_ptr af)
// display results
displayTime(startTime, finalTime);
displayCheckResult(res);
return res;
}
/******************************************************************************
......@@ -344,29 +387,60 @@ void runOnTheFlyMC(const string &algorithm, auto k, spot::twa_graph_ptr af)
******************************************************************************/
int main(int argc, char **argv)
{
CLI::App app{"PMC-SOG : Parallel Model Checking tool based on Symbolic Observation Graphs"};
app.add_option("--n", nb_th, "Number of threads/workers to be created (default: 1)")
->default_val(1)
app.add_option("--n", nb_th, "Number of threads to be created (default: 1)")
->type_name("Integer")
->check(CLI::PositiveNumber);
string net = "";
app.add_option("--net", net, "Petri net file")
->type_name("Path")
->required()
->check(CLI::ExistingFile);
string formula = "";
app.add_option("--ltl", formula, "LTL property file")
->type_name("Path")
->required()
->check(CLI::ExistingFile);
string method = "";
app.add_option("--method", method, "Method to create threads or/and set if model-checking should be performed on the fly")
->required();
string thread_library = "c++";
app.add_option("--thread", thread_library, "Thread library (default: c++)")->check(CLI::IsMember({"posix", "c++"}));
bool por{false};
app.add_flag("--por,!--no-por", por, "Apply partial order reductions (default: false)");
bool explicit_mc{false};
CLI::Option *exp_opt = app.add_flag("--explicit", explicit_mc, "Run explicit model-checking")->group("Explicit MC");
// progressive construction can be used only when using on-the-fly model-checking
bool progressive{false};
app.add_flag("--progressive,!--no-progressive", progressive, "Use a progressive construction of the SOG (default: false)")->excludes(exp_opt);
// emptiness check algorithm is only needed when using on-the-fly model-checking
string algorithm = "";
app.add_option("--emptiness-check", algorithm, "Number of threads/workers to be created");
app.add_option("--emptiness-check", algorithm, "Spot emptiness-check algorithm")->excludes(exp_opt)->group("On-the-fly MC");
// lace is only needed when using explicit model-checking
bool uselace{false};
app.add_flag("--lace,!--no-lace", uselace, "Use the work-stealing framework Lace (default: false)")->needs(exp_opt)->group("Explicit MC");
bool canonization{false};
app.add_flag("--canonization,!--no-canonization", canonization, "Apply canonization to the SOG (default: false)")->needs(exp_opt)->group("Explicit MC");
// build only the SOG is possible only in explicit model-checking
bool only_sog{false};
app.add_flag("--only-sog", only_sog, "Only builds the SOG")->needs(exp_opt)->group("Explicit MC");
bool dot_sog{false};
app.add_flag("--dot-sog", dot_sog, "Save the SOG in a dot file")->needs(exp_opt)->group("Print");
bool dot_formula{false};
app.add_flag("--dot-formula", dot_formula, "Save the automata of the negated formula in a dot file")->group("Print");
bool counter_example{false};
app.add_flag("--counter-example", counter_example, "Save the counter example in a dot file")->needs(exp_opt)->group("Print");
CLI11_PARSE(app, argc, argv);
......@@ -415,14 +489,14 @@ int main(int argc, char **argv)
if (n_tasks == 1)
{
// On-the-fly multi-core model checking
if (isValidMultiCoreMCOption(n_tasks, method))
if (!explicit_mc)
{
// get the corresponding multi-core model-checker
ModelCheckBaseMT *mcl = getMultiCoreMC(Rnewnet, method, nb_th);
ModelCheckBaseMT *mcl = getMultiCoreMC(Rnewnet, nb_th, thread_library, progressive, por);
// build automata of the negation of the formula
auto d = spot::make_bdd_dict();
spot::twa_graph_ptr af = formula2Automaton(negate_formula.f, d);
spot::twa_graph_ptr af = formula2Automaton(negate_formula.f, d, dot_formula);
// create the SOG
mcl->loadNet();
......@@ -440,7 +514,6 @@ int main(int argc, char **argv)
}
else // build only SOG
{
bool uselace = ((method == "lc") || (method == "l"));
threadSOG DR(Rnewnet, nb_th, uselace);
LDDGraph g(&DR);
......@@ -464,22 +537,7 @@ int main(int argc, char **argv)
cout << "# of threads to be created: " << nb_th << endl;
// select a method to construct the SOG
unsigned int constructionOption;
if (method == "p")
{
cout << "Construction with pthread library." << endl;
constructionOption = 0;
}
else if (method == "pc")
{
cout << "Canonized construction with pthread library." << endl;
constructionOption = 1;
}
else
{
cout << "Partial Order Reduction with pthread library." << endl;
constructionOption = 2;
}
int constructionOption = getMultiCoreBuildOption(thread_library, canonization, por);
// build the distributed SOG
DR.computeDSOG(g, constructionOption);
......@@ -487,33 +545,22 @@ int main(int argc, char **argv)
// print SOG information
g.printCompleteInformation();
cout << "\nPerform Model checking? ";
char c;
cin >> c;
if (c == 'y')
// run model checking process
if (!only_sog)
{
auto d = spot::make_bdd_dict();
// build the negation of the formula
spot::twa_graph_ptr af = formula2Automaton(negate_formula.f, d);
cout << "Want to save the automata of the formula in a dot file? ";
cin >> c;
if (c == 'y')
{
saveGraph(af, formula + ".dot");
}
spot::twa_graph_ptr af = formula2Automaton(negate_formula.f, d, dot_formula);
// build a twa graph of the SOG
// TODO: Why do we translate the SOG into twa ?
cout << "\n\nTranslating SOG to SPOT ..." << endl;
cout << "\nTranslating SOG to SPOT ..." << endl;
spot::twa_graph_ptr k = spot::make_twa_graph(
std::make_shared<SogKripke>(d, DR.getGraph(), Rnewnet.getListTransitionAP(), Rnewnet.getListPlaceAP()),
spot::twa::prop_set::all(), true);
cout << "\nWant to save the SOG in a dot file? ";
cin >> c;
if (c == 'y')
if (dot_sog)
{
saveGraph(af, net + ".dot", "ka");
saveGraph(af, "SOG.dot", "ka");
}
cout << endl;
......@@ -522,7 +569,7 @@ int main(int argc, char **argv)
displayCheckResult(run == nullptr);
// display a counter-example if it exists
if (run)
if (run && counter_example)
{
run->highlight(5);
saveGraph(k, "counter-example.dot", ".kA");
......@@ -542,21 +589,13 @@ int main(int argc, char **argv)
<< endl;
// On-the-fly hybrid model checking
if (isValidHybridMCOption(nb_th, method))
if (!explicit_mc)
{
n_tasks--;
// ID of the task performing the model checking
int mc_task = n_tasks;
// display information about model checking processes
if (task_id == mc_task)
{
cout << "Model checking on the fly..." << endl;
cout << " 1 process will perform Model checking" << endl;
cout << " " << n_tasks << " process(es) will build the Distributed SOG" << endl;
}
// creates model-checking process
MPI_Comm gprocess;
MPI_Comm_split(MPI_COMM_WORLD, task_id == mc_task ? 0 : 1, task_id, &gprocess);
......@@ -564,7 +603,7 @@ int main(int argc, char **argv)
// computes the SOG in processes different to the model-checker one
if (task_id != mc_task)
{
CommonSOG *DR = getHybridMC(Rnewnet, method, gprocess);
CommonSOG *DR = getHybridMC(Rnewnet, thread_library, progressive, por, gprocess);
cout << "# tasks: " << n_tasks << endl;
// compute the distributed SOG
......@@ -573,11 +612,13 @@ int main(int argc, char **argv)
}
else // computes the on-the-fly model-checking in the mc process
{
cout << "On the fly Model checker by process " << task_id << endl;
cout << "Model checking on the fly..." << endl;
cout << " 1 process will perform Model checking: process " << task_id << endl;
cout << " " << n_tasks << " process(es) will build the Distributed SOG" << endl;
// build the negation of the formula
auto d = spot::make_bdd_dict();
spot::twa_graph_ptr af = formula2Automaton(negate_formula.f, d);
spot::twa_graph_ptr af = formula2Automaton(negate_formula.f, d, dot_formula);
// build the SOG
auto k = std::make_shared<HybridKripke>(d, Rnewnet.getListTransitionAP(), Rnewnet.getListPlaceAP(), Rnewnet);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment