Skip to content
Snippets Groups Projects
main.cpp 21.7 KiB
Newer Older
  • Learn to ignore specific revisions
  • #include <ctime>
    
    Hiba Ouni's avatar
    Hiba Ouni committed
    #include <chrono>
    #include <iostream>
    #include <string>
    
    Hiba Ouni's avatar
    Hiba Ouni committed
    #include <fstream>
    
    Hiba Ouni's avatar
    Hiba Ouni committed
    #include <mpi.h>
    
    #include <CLI11.hpp>
    
    #include "LDDGraph.h"
    
    Jaime Arias's avatar
    Jaime Arias committed
    #include <spot/kripke/kripke.hh>
    
    #include "MCMultiCore/ModelCheckerCPPThread.h"
    #include "MCMultiCore/ModelCheckerTh.h"
    #include "MCMultiCore/ModelCheckThReq.h"
    
    #include "MCMultiCore/MCCPPThPor.h"
    
    Hiba Ouni's avatar
    Hiba Ouni committed
    #include "threadSOG.h"
    #include "HybridSOG.h"
    
    #include "Hybrid/MCHybrid/MCHybridSOG.h"
    
    Hiba Ouni's avatar
    Hiba Ouni committed
    #include <spot/misc/version.hh>
    #include <spot/twaalgos/dot.hh>
    #include <spot/tl/parse.hh>
    #include <spot/tl/print.hh>
    #include <spot/twaalgos/translate.hh>
    #include <spot/twaalgos/emptiness.hh>
    #include <spot/tl/apcollect.hh>
    
    #include <spot/ta/taproduct.hh>
    #include <spot/twa/twaproduct.hh>
    #include <spot/twaalgos/gtec/gtec.hh>
    
    #include "NewNet.h"
    #include "SogTwa.h"
    
    #include "SogKripke.h"
    
    Hiba Ouni's avatar
    Hiba Ouni committed
    #include "SogKripkeTh.h"
    
    #include "Hybrid/HybridKripke.h"
    #include "Hybrid/MCHybridReq/MCHybridSOGReq.h"
    
    Chiheb Amer Abid's avatar
    Chiheb Amer Abid committed
    #include "SylvanWrapper.h"
    
    #include "PMCSOGConfig.h"
    
    #include "Hybrid/MCHybridReqPOR/MCHybridSOGReqPOR.h"
    #include "Hybrid/MCHybridPOR/MCHybridSOGPOR.h"
    
    #include "algorithm/CNDFS.h"
    
    #include <typeinfo>
    
    #include <atomic>
    
    Ghofrane Amaimi's avatar
    Ghofrane Amaimi committed
    #include <thread>
    #include <vector>
    
    Hiba Ouni's avatar
    Hiba Ouni committed
    using namespace std;
    
    Hiba Ouni's avatar
    Hiba Ouni committed
    int n_tasks, task_id;
    
    Jaime Arias's avatar
    Jaime Arias committed
    unsigned int nb_th = 1; // used by the distributed model checker
    
    
    struct Formula
    {
        spot::formula f;
        set<string> propositions;
    };
    
    
    Jaime Arias's avatar
    Jaime Arias committed
    /**
     * 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
     *
     * @param fileName Path to LTL formula
     * @return Formula
     */
    Formula negateFormula(const string &fileName)
    {
        string input;
        set<string> transitionSet;
        ifstream file(fileName);
    
        cout << "______________________________________" << endl;
        cout << "Fetching formula ... " << endl;
    
        if (!file.is_open())
        {
            cout << "Cannot open formula file" << endl;
            exit(0);
        }
    
        getline(file, input);
        cout << "        Loaded formula: " << input << endl;
        file.close();
    
        spot::parsed_formula pf = spot::parse_infix_psl(input);
        if (pf.format_errors(std::cerr))
            exit(0);
    
        spot::formula fo = pf.f;
        if (!fo.is_ltl_formula())
        {
            std::cerr << "Only LTL formulas are supported.\n";
            exit(0);
        }
    
        spot::atomic_prop_set *p_list = spot::atomic_prop_collect(fo, nullptr);
        for (const auto &i : *p_list)
        {
            transitionSet.insert(i.ap_name());
        }
        cout << "Formula in SPIN format: ";
        print_spin_ltl(std::cout, fo) << endl;
    
        cout << "Building negation of the formula ... ";
        spot::formula not_f = spot::formula::Not(pf.f);
        cout << "done\n"
             << endl;
    
        return {not_f, transitionSet};
    
    Hiba Ouni's avatar
    Hiba Ouni committed
    }
    
    
    /**
     * Convert a formula inton an automaton
     *
     * @param f  Formula to be converted
     * @param bdd  BDD structure
    
    Jaime Arias's avatar
    Jaime Arias committed
     * @param save_dot Save the automaton of the negated formula in a dot file
    
     * @return spot::twa_graph_ptr
     */
    
    Jaime Arias's avatar
    Jaime Arias committed
    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);
    
    Jaime Arias's avatar
    Jaime Arias committed
        cout << "Formula automata built." << endl;
    
        // save the generated automaton in a dot file
        if (save_dot)
        {
            saveGraph(af, "negated_formula.dot");
        }
    
    
        return af;
    
    /**
     * Print the result of the verification
     *
     * @param res flag indicating if the property is true or false
     */
    void displayCheckResult(bool res)
    {
        if (res)
    
    Jaime Arias's avatar
    Jaime Arias committed
            cout << "\nProperty is verified..." << endl;
    
    Jaime Arias's avatar
    Jaime Arias committed
            cout << "\nProperty is violated..." << endl;
    
    
    /**
     * Display the elapsed time between two times
     *
     * @param startTime initial time
     * @param finalTime final time
     */
    void displayTime(auto startTime, auto finalTime)
    {
        cout << "Verification duration : " << std::chrono::duration_cast<std::chrono::milliseconds>(finalTime - startTime).count() << " milliseconds\n";
    }
    
    /**
     * Print information of the execution
     *
     * @param net Net to be verified
     * @param formula  Formula to be verified
     * @param algorithm Emptiness check algorithm to be used
     * @param nb_th  Number of threads of the execution
     */
    void displayToolInformation(const string &net, const string &formula, const string &algorithm, int nb_th)
    {
        // computes the current year
        time_t t = std::time(nullptr);
        tm *const pTInfo = std::localtime(&t);
        int year = 1900 + pTInfo->tm_year;
    
        cout << "PMC-SOG: Parallel Model Checking tool based on Symbolic Observation Graphs" << endl;
        cout << "Version " << PMCSOG_VERSION_MAJOR << "." << PMCSOG_VERSION_MINOR << "." << PMCSOG_VERSION_PATCH << endl;
        cout << "(c) 2018 - " << year << endl;
        cout << endl;
        cout << "          Net file: " << net << endl;
        cout << "      Formula file: " << formula << endl;
        cout << "Checking algorithm: " << algorithm << endl;
        cout << "         # threads: " << nb_th << endl;
    }
    
    /**
     * Get the multi-core model-checker
     *
     * @param net Net to be verified
     * @param nb_th Number of threads
    
    Jaime Arias's avatar
    Jaime Arias committed
     * @param thread_library Thread library
     * @param progressive Flag for a progressive construction of the SOG
     * @param por Flag for partial order reduction
    
     * @return ModelCheckBaseMT*
     */
    
    Jaime Arias's avatar
    Jaime Arias committed
    ModelCheckBaseMT *getMultiCoreMC(NewNet &net, int nb_th, const string &thread_library, bool progressive, bool por)
    
    {
        ModelCheckBaseMT *mcl = nullptr;
    
        // select the right model-checking algorithm
    
    Jaime Arias's avatar
    Jaime Arias committed
        if (thread_library == "posix")
    
    Jaime Arias's avatar
    Jaime Arias committed
            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);
            }
    
    Jaime Arias's avatar
    Jaime Arias committed
        else if (thread_library == "c++")
    
    Jaime Arias's avatar
    Jaime Arias committed
            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);
            }
    
    Jaime Arias's avatar
    Jaime Arias committed
        else
    
    Jaime Arias's avatar
    Jaime Arias committed
            cout << thread_library << " is not a valid thread library for the multi-core version" << endl;
            exit(-1);
    
    Jaime Arias's avatar
    Jaime Arias committed
    
        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")
    
    Jaime Arias's avatar
    Jaime Arias committed
            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;
                }
            }
    
    Jaime Arias's avatar
    Jaime Arias committed
            cout << thread_library << " is not a valid threads library for the multi-core version" << endl;
    
            exit(-1);
        }
    }
    
    /**
     * Get the Hybrid model-checker
     *
     * @param net Net to be verified
     * @param method  Hybrid implementation
    
    Jaime Arias's avatar
    Jaime Arias committed
     * @param progressive Flag for a progressive construction of the SOG
     * @param por Flag for partial order reduction
    
     * @param communicator MPI communicator
     * @return CommonSOG*
     */
    
    Jaime Arias's avatar
    Jaime Arias committed
    CommonSOG *getHybridMC(NewNet &net, const string &thread_library, bool progressive, bool por, MPI_Comm &communicator)
    
    Jaime Arias's avatar
    Jaime Arias committed
    
        if (thread_library == "c++")
    
    Jaime Arias's avatar
    Jaime Arias committed
            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);
                }
            }
    
    Jaime Arias's avatar
    Jaime Arias committed
            cout << thread_library << " is not a valid thread library for the hybrid version" << endl;
            exit(-1);
    
    Jaime Arias's avatar
    Jaime Arias committed
    
    
    Jaime Arias's avatar
    Jaime Arias committed
     * Run the on-the-fly model-checking algorithm
    
     * @param algorithm Sequential emptiness-check algorithm
    
    Jaime Arias's avatar
    Jaime Arias committed
     * @param k Kripke structure of the SOG
     * @param af Automata  of the negated formula
     * @return bool
    
    Jaime Arias's avatar
    Jaime Arias committed
    bool runOnTheFlyMC(const string &algorithm, auto k, spot::twa_graph_ptr af)
    
    {
        bool res = false;
        std::chrono::steady_clock::time_point startTime, finalTime;
    
        cout << "\nPerforming on the fly Model-Checking..." << endl;
    
        if (algorithm != "")
        {
            // set the synchronized product of the SOG and the negated formula
            shared_ptr<spot::twa_product> product = make_shared<spot::twa_product>(k, af);
    
    
            // set the emptiness check
            const char *err;
            spot::emptiness_check_instantiator_ptr echeck_inst = spot::make_emptiness_check_instantiator(algorithm.c_str(), &err);
    
            if (!echeck_inst)
            {
                cerr << "Failed to parse argument near '" << err << "'" << endl;
                cerr << "Spot unknown emptiness algorithm" << endl;
                exit(2);
            }
            else
                cout << "Spot emptiness check algorithm: " << algorithm << endl;
    
            // computes the on-the-fly emptiness check of the synchronized product
            startTime = std::chrono::steady_clock::now();
            spot::emptiness_check_ptr echptr = echeck_inst->instantiate(product);
            res = (echptr->check() == nullptr);
            finalTime = std::chrono::steady_clock::now();
        }
        else
        {
            // computes the intersection between the SOG and the negated formula
            startTime = std::chrono::steady_clock::now();
            res = (k->intersecting_run(af) == nullptr);
            finalTime = std::chrono::steady_clock::now();
        }
    
        // display results
        displayTime(startTime, finalTime);
        displayCheckResult(res);
    
    Jaime Arias's avatar
    Jaime Arias committed
    
        return res;
    
    /**
     * Run the on-the-fly parallel model-checking algorithm
     *
     * @param algorithm Parallel emptiness-check algorithm
     *
     * TODO: implement this
     */
    
    Ghofrane Amaimi's avatar
    Ghofrane Amaimi committed
    //bool runOnTheFlyParallelMC(const string &algorithm) {}
    
    /******************************************************************************
     * Main function
     ******************************************************************************/
    int main(int argc, char **argv)
    {
        CLI::App app{"PMC-SOG : Parallel Model Checking tool based on Symbolic Observation Graphs"};
    
    
    Jaime Arias's avatar
    Jaime Arias committed
        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")
    
    Jaime Arias's avatar
    Jaime Arias committed
            ->type_name("Path")
    
            ->required()
            ->check(CLI::ExistingFile);
    
        string formula = "";
        app.add_option("--ltl", formula, "LTL property file")
    
    Jaime Arias's avatar
    Jaime Arias committed
            ->type_name("Path")
    
            ->required()
            ->check(CLI::ExistingFile);
    
    
    Jaime Arias's avatar
    Jaime Arias committed
        string thread_library = "c++";
        app.add_option("--thread", thread_library, "Thread library (default: c++)")->check(CLI::IsMember({"posix", "c++"}));
    
    Jaime Arias's avatar
    Jaime Arias committed
        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)->group("On-the-fly MC");
    
    Jaime Arias's avatar
    Jaime Arias committed
    
        // emptiness check algorithm is only needed when using on-the-fly model-checking
    
        string algorithm = "";
    
    Jaime Arias's avatar
    Jaime Arias committed
        app.add_option("--emptiness-check", algorithm, "Spot emptiness-check algorithm")->excludes(exp_opt)->group("On-the-fly MC");
    
    
    Jaime Arias's avatar
    Jaime Arias committed
        // lace is only available when using explicit multi-core model-checking
    
    Jaime Arias's avatar
    Jaime Arias committed
        bool uselace{false};
    
    Jaime Arias's avatar
    Jaime Arias committed
        app.add_flag("--lace,!--no-lace", uselace, "Use the work-stealing framework Lace. Available only in multi-core (default: false)")->needs(exp_opt)->group("Explicit MC");
    
    Jaime Arias's avatar
    Jaime Arias committed
    
    
    Jaime Arias's avatar
    Jaime Arias committed
        // canonization is only available in the explicit multi-core version. In the hybrid is always true
    
    Jaime Arias's avatar
    Jaime Arias committed
        bool canonization{false};
    
    Jaime Arias's avatar
    Jaime Arias committed
        app.add_flag("--canonization,!--no-canonization", canonization, "Apply canonization to the SOG. Available only in multi-core (default: false)")->needs(exp_opt)->group("Explicit MC");
    
    Jaime Arias's avatar
    Jaime Arias committed
    
        // build only the SOG is possible only in explicit model-checking
        bool only_sog{false};
    
    Jaime Arias's avatar
    Jaime Arias committed
        app.add_flag("--only-sog", only_sog, "Only builds the SOG. Available only in multi-core")->needs(exp_opt)->group("Explicit MC");
    
    Jaime Arias's avatar
    Jaime Arias committed
    
        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);
    
        // MPI arguments
    
        MPI_Init(&argc, &argv);
        MPI_Comm_size(MPI_COMM_WORLD, &n_tasks);
        MPI_Comm_rank(MPI_COMM_WORLD, &task_id);
    
    
        // Display information of the tool
        if (!task_id)
        {
            displayToolInformation(net, formula, algorithm, nb_th);
        }
    
        // Check the number of processes
        if (n_tasks <= 0)
        {
            cout << "Number of tasks <= 0 " << endl;
            exit(0);
        }
    
        // Check the number of threads
        if (nb_th <= 0)
        {
            cout << "Number of thread <= 0 " << endl;
            exit(0);
        }
    
        // hybrid version requires two or more threads
        if (n_tasks > 1 && nb_th < 2)
        {
            if (task_id == 0)
                cout << "The hybrid version requires more than 1 threads\n"
                     << endl;
            exit(0);
    
    
        // Get the negation of the LTL formula
        Formula negate_formula = negateFormula(formula);
        NewNet Rnewnet(net.c_str(), negate_formula.propositions);
        cout << endl;
    
        /**************************************************************************
         * Multi-core version
         **************************************************************************/
        if (n_tasks == 1)
        {
    
    Ghofrane Amaimi's avatar
    Ghofrane Amaimi committed
            cout<< "Hello Multi-core version" <<endl;
    
            // On-the-fly multi-core model checking
    
    Jaime Arias's avatar
    Jaime Arias committed
            if (!explicit_mc)
    
            {
                // get the corresponding multi-core model-checker
    
    Jaime Arias's avatar
    Jaime Arias committed
                ModelCheckBaseMT *mcl = getMultiCoreMC(Rnewnet, nb_th, thread_library, progressive, por);
    
    
                // build automata of the negation of the formula
    
                auto d = spot::make_bdd_dict();
    
    Jaime Arias's avatar
    Jaime Arias committed
                spot::twa_graph_ptr af = formula2Automaton(negate_formula.f, d, dot_formula);
    
                // twa_graph class
    
                shared_ptr<spot::twa_graph> aa = formula2Automaton(negate_formula.f, d, dot_formula);
    
    
                // create the SOG
    
                mcl->loadNet();
    
                // run on the fly parallel model-checking
                // TODO: Implement here Ghofrane's algorithms
                if (algorithm == "UFSCC" || algorithm == "CNDFS")
                {
    
    Ghofrane Amaimi's avatar
    Ghofrane Amaimi committed
    
    //                cout<<"pointeur sur sog "<< typeid(mcl).name() <<endl;
    //                cout <<"pointeur sur BA "<< typeid(aa).name() <<endl;
    
                    CNDFS cndfs;
    
                    //CNDFS cndfs(*mcl, aa);
    
    Ghofrane Amaimi's avatar
    Ghofrane Amaimi committed
                    //cndfs.DfsBlue(*mcl, aa);
                    thread thread_1 (cndfs.DfsBlue,ref(*mcl),ref(aa));
                    thread thread_2 (cndfs.DfsBlue,ref(*mcl),ref(aa));
                    thread_1.join();
                    thread_2.join();
                   // n.spawnThreads(2,*mcl,aa);
    
                    return(0);
    
                }
                else // run on the fly sequential model-checking
                {
                    auto k = std::make_shared<SogKripkeTh>(d, mcl, Rnewnet.getListTransitionAP(), Rnewnet.getListPlaceAP());
    
                    //runOnTheFlyMC(algorithm, k, af);
    
    
                // stop model checker process
    
                mcl->finish();
    
    
                // print SOG information
    
                mcl->getGraph()->printCompleteInformation();
    
                delete mcl;
            }
    
            else // build only SOG
            {
    
                threadSOG DR(Rnewnet, nb_th, uselace);
                LDDGraph g(&DR);
    
    
                // Sequential  construction of the SOG
                // TODO: There is no way to run Model-checking when the SOG is built sequentially?
                if (nb_th == 1)
                {
    
                    cout << "\n****************** Sequential version ******************* \n"<< endl;
    
    
                    // build sequential SOG
    
                    DR.computeSeqSOG(g);
    
    
                    // print SOG information
    
                    g.printCompleteInformation();
    
                }
                else // Multi-thread construction of the SOG
                {
                    cout << "\n******************* Multi-thread version ****************** \n"
                         << endl;
                    cout << "# of threads to be created: " << nb_th << endl;
    
                    // select a method to construct the SOG
    
    Jaime Arias's avatar
    Jaime Arias committed
                    int constructionOption = getMultiCoreBuildOption(thread_library, canonization, por);
    
                    // build the distributed SOG
                    DR.computeDSOG(g, constructionOption);
    
                    // print SOG information
                    g.printCompleteInformation();
    
    Jaime Arias's avatar
    Jaime Arias committed
                    // run model checking process
                    if (!only_sog)
    
                        auto d = spot::make_bdd_dict();
    
    
                        // build the negation of the formula
    
    Jaime Arias's avatar
    Jaime Arias committed
                        spot::twa_graph_ptr af = formula2Automaton(negate_formula.f, d, dot_formula);
    
                        // build a twa graph of the SOG
    
    Jaime Arias's avatar
    Jaime Arias committed
                        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);
    
    Jaime Arias's avatar
    Jaime Arias committed
                        if (dot_sog)
    
    Jaime Arias's avatar
    Jaime Arias committed
                            saveGraph(af, "SOG.dot", "ka");
    
                        cout << endl;
    
                        // computes the explicit synchronization product
                        auto run = k->intersecting_run(af);
                        displayCheckResult(run == nullptr);
    
                        // display a counter-example if it exists
    
    Jaime Arias's avatar
    Jaime Arias committed
                        if (run && counter_example)
    
                            run->highlight(5);
    
                            saveGraph(k, "counter-example.dot", ".kA");
                            cout << "Check the dot file to get a counter-example" << endl;
                        }
    
        /**************************************************************************
         * Hybrid version
         **************************************************************************/
        else
        {
    
    Ghofrane Amaimi's avatar
    Ghofrane Amaimi committed
            cout << "hello hybrid version" <<endl;
    
            if (task_id == 0)
                cout << "\n************** Hybrid version ****************\n"
                     << endl;
    
            // On-the-fly hybrid model checking
    
    Jaime Arias's avatar
    Jaime Arias committed
            if (!explicit_mc)
    
            {
                n_tasks--;
    
                // ID of the task performing the model checking
                int mc_task = n_tasks;
    
                // creates model-checking process
                MPI_Comm gprocess;
                MPI_Comm_split(MPI_COMM_WORLD, task_id == mc_task ? 0 : 1, task_id, &gprocess);
    
                // computes the SOG in processes different to the model-checker one
                if (task_id != mc_task)
                {
    
    Jaime Arias's avatar
    Jaime Arias committed
                    CommonSOG *DR = getHybridMC(Rnewnet, thread_library, progressive, por, gprocess);
    
                    cout << "# tasks: " << n_tasks << endl;
    
                    // compute the distributed SOG
                    LDDGraph g(DR);
                    DR->computeDSOG(g);
                }
                else // computes the on-the-fly model-checking in the mc process
                {
    
    Jaime Arias's avatar
    Jaime Arias committed
                    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();
    
    Jaime Arias's avatar
    Jaime Arias committed
                    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);
    
    
    Ghofrane Amaimi's avatar
    Ghofrane Amaimi committed
                   // runOnTheFlyMC(algorithm, k, af);
    
            else // build only the SOG
            {
                HybridSOG DR(Rnewnet);
                LDDGraph g(&DR);
                cout << endl;
    
                if (task_id == 0)
                    cout << "Building the Distributed SOG by " << n_tasks << " processes..." << endl;
    
                // computes the distributed SOG
                DR.computeDSOG(g);
            }
    
        MPI_Finalize();
    
        return (EXIT_SUCCESS);
    }