diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 75f543caf8688ac67a8a55cdc045f40a1066ef3e..9f3909bb640b559cf8234ec3e03059d4e15b6543 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -76,12 +76,15 @@ add_executable(mc-sog main.cpp
         MCMultiCore/ModelCheckerCPPThread.cpp MCMultiCore/ModelCheckerCPPThread.h
         MCMultiCore/ModelCheckerTh.cpp MCMultiCore/ModelCheckerTh.h
         MCMultiCore/MCThReqPor.cpp MCMultiCore/MCThReqPor.h
+        MCMultiCore/MCCPPThPor.cpp MCMultiCore/MCCPPThPor.h
         threadSOG.cpp threadSOG.h
         HybridSOG.cpp HybridSOG.h
         Hybrid/MCHybrid/MCHybridSOG.cpp Hybrid/MCHybrid/MCHybridSOG.h
         MCMultiCore/ModelCheckThReq.cpp MCMultiCore/ModelCheckThReq.h
         Hybrid/MCHybridReq/MCHybridSOGReq.cpp
         Hybrid/MCHybridReq/MCHybridSOGReq.h
+        Hybrid/MCHybridReqPOR/MCHybridSOGReqPOR.cpp
+        Hybrid/MCHybridReqPOR/MCHybridSOGReqPOR.h
         misc/md5_hash.h)
 
 
diff --git a/src/CommonSOG.cpp b/src/CommonSOG.cpp
index e0f1eebec390efa864c15a26ebb19277c9cbd7ad..950ed44199970b3d0a09dbb245e0992eef2daf17 100644
--- a/src/CommonSOG.cpp
+++ b/src/CommonSOG.cpp
@@ -43,7 +43,7 @@ MDD CommonSOG::get_successor(const MDD &From, const int &t) {
 }
 
 MDD CommonSOG::get_pred(const MDD &From, const int &t) {
-    return SylvanWrapper::lddmc_firing_mono(From, m_tb_relation[(t)].getPlus(), m_tb_relation[t].getMinus());
+    return SylvanWrapper::lddmc_firing_mono(From, m_tb_relation[t].getPlus(), m_tb_relation[t].getMinus());
 }
 
 MDD CommonSOG::ImageForward(const MDD& From) {
@@ -188,7 +188,9 @@ void CommonSOG::loadNetFromFile() {
 
     m_transitionName = &m_net->transitionName;
     m_placeName = &m_net->m_placePosName;
-
+    for (const auto& t : m_observable) {
+        m_transitions[t].mObservable=true;
+    }
 
     cout << "Nombre de places : " << m_nbPlaces << endl;
     cout << "Derniere place : " << m_net->places[m_nbPlaces - 1].name << endl;
@@ -236,11 +238,19 @@ void CommonSOG::loadNetFromFile() {
     }
     delete[] prec;
     delete[] postc;
+    for (auto elt : m_transitions){
+        cout<<"New transition"<<endl;
+        for (auto pre:elt.pre) {
+            cout<<pre.first<<" ";
+        }
+        cout<<"\n";
+    }
 }
 void CommonSOG::AddConflict2(const MDD &S, const int &transition, Set &ample) {
     auto haveCommonPre = [&](vector<pair<int, int>> &preT1, vector<pair<int, int>> &preT2) -> bool {
         for (auto &elt1: preT1) {
             for (auto &elt2: preT2) {
+                if (elt1.first<elt2.first) break;
                 if (elt1.first == elt2.first) return true;
             }
         }
@@ -248,25 +258,32 @@ void CommonSOG::AddConflict2(const MDD &S, const int &transition, Set &ample) {
     };
     if (SylvanWrapper::lddmc_intersect(S, get_pred(get_successor(S,transition),transition))==S) {
         for(auto i = 0; i < m_transitions.size(); ++i) {
-            auto &preT1 = m_transitions[i].pre;
-            auto &preT2 = m_transitions[transition].pre;
-            if (haveCommonPre(preT1, preT2)) ample.insert(i);
+            if (i!=transition) {
+                auto &preT1 = m_transitions[i].pre;
+                auto &preT2 = m_transitions[transition].pre;
+                if (haveCommonPre(preT1, preT2)) ample.insert(i);
+            }
+
         }
     }
     else {
-        if (!SylvanWrapper::isFirable(S,transition)) {
+        if (!SylvanWrapper::SylvanWrapper::lddmc_firing_mono(S,m_tb_relation[transition].getMinus(),m_tb_relation[transition].getPlus())) {
             for(auto i = 0; i < m_transitions.size(); ++i) {
-                auto &preT = m_transitions[transition].pre;
-                auto &postT1 = m_transitions[i].post;
-                if (haveCommonPre(preT, postT1)) ample.insert(i);
+                if (i!=transition) {
+                    auto &preT = m_transitions[transition].pre;
+                    auto &postT1 = m_transitions[i].post;
+                    if (haveCommonPre(preT, postT1)) ample.insert(i);
+                }
             }
         }
         else {
             for(auto i = 0; i < m_transitions.size(); ++i) {
-                auto &preT = m_transitions[transition].pre;
-                auto &postT1 = m_transitions[i].post;
-                auto &preT1 = m_transitions[i].pre;
-                if (haveCommonPre(preT, postT1) || haveCommonPre(preT,preT1)) ample.insert(i);
+                if (i!=transition) {
+                    auto &preT = m_transitions[transition].pre;
+                    auto &postT1 = m_transitions[i].post;
+                    auto &preT1 = m_transitions[i].pre;
+                    if (haveCommonPre(preT, postT1) || haveCommonPre(preT, preT1)) ample.insert(i);
+                }
             }
         }
     }
@@ -275,12 +292,12 @@ void CommonSOG::AddConflict(const MDD &S, const int &transition, Set &ample) {
     auto haveCommonPre = [&](vector<pair<int, int>> &preT1, vector<pair<int, int>> &preT2) -> bool {
         for (auto &elt1: preT1) {
             for (auto &elt2: preT2) {
+                if (elt1.first<elt2.first) break;
                 if (elt1.first == elt2.first) return true;
             }
         }
         return false;
     };
-   // cout<<"Transition to deal with : "<<transition<<endl;
     if (SylvanWrapper::isFirable(S,m_tb_relation[transition].getMinus())) {
         //cout<<"Checked\n";
         for ( auto i = 0; i < m_transitions.size(); ++i) {
@@ -303,7 +320,6 @@ void CommonSOG::AddConflict(const MDD &S, const int &transition, Set &ample) {
 
 Set CommonSOG::computeAmple(const MDD &s) {
     Set ample;
-
     // Compute enabled transitions in s
     for (auto index=0;index<m_tb_relation.size();++index) {
         if (SylvanWrapper::isFirable(s,m_tb_relation[index].getMinus())) {
@@ -323,17 +339,16 @@ Set CommonSOG::computeAmple2(const MDD &S) {
     MDD pre,img;
     do {
 
-        for (auto index=0;index<m_tb_relation.size();++index) {
-            if (SylvanWrapper::isFirable(S,m_tb_relation[index].getMinus())) {
+       for (auto index=0;index<m_tb_relation.size();++index) {
+            if (SylvanWrapper::lddmc_firing_mono(S,m_tb_relation[index].getMinus(),m_tb_relation[index].getPlus())) {
                 ample.insert(index); break;
             }
         }
+
        for (const auto& t: ample) {
            AddConflict2(S, t, ample);
        }
-        //AddConflict2(S, *ample.begin(), ample);
-
-        img=lddmc_true;
+        img=lddmc_false;
         for (const auto& t : ample)
             img=SylvanWrapper::lddmc_union_mono(img,SylvanWrapper::lddmc_firing_mono(S,m_tb_relation[t].getMinus(),m_tb_relation[t].getPlus()));
         pre=lddmc_false;
@@ -351,32 +366,26 @@ MDD CommonSOG::saturatePOR(const MDD &s, Set& tObs,bool &div,bool &dead) {
     set<MDD> myStack;
     myStack.insert(s);
     tObs.clear();
-    MDD To=lddmc_false;
+    MDD To {lddmc_false};
     do {
         Reach1=Reach2;
-
-        ample=computeAmple(From);
+        ample=computeAmple2(From);
         if (ample.empty()) {
             dead=true;
         }
         else {
             for (const auto & t : ample) {
                 MDD succ=SylvanWrapper::lddmc_firing_mono(From,m_tb_relation[t].getMinus(),m_tb_relation[t].getPlus());
-                if (succ!=lddmc_true && succ!=lddmc_false) {
+                if (succ!=lddmc_false) {
                     //cout<<"Transition of ample : "<<t<<endl;
                     if (m_transitions[t].mObservable) {
-                        //cout<<"Obs detected "<<t<<endl;
                         tObs.insert(t);
                     } else {
-                       //if (!SylvanWrapper::isFirable(From,m_tb_relation[t].getMinus())) exit(0);
-//                    //cout<<"From :"<<From<<"by transition "<<t<<" succ : "<<succ<<endl;
-                        //Compute div
-                        if (myStack.find(succ) != myStack.end()) {
+                       if (myStack.find(succ) != myStack.end()) {
                             div = true;
-                            //cout<<"loop"<<endl;
                             for (uint16_t i = 0; i < m_tb_relation.size(); ++i) {
                                 MDD newM=SylvanWrapper::lddmc_firing_mono(From,m_tb_relation[i].getMinus(),m_tb_relation[i].getPlus());
-                                if (newM!=lddmc_false && newM!=lddmc_true) {
+                                if (newM!=lddmc_false) {
                                     if (m_transitions[i].mObservable) {
                                         tObs.insert(i);
                                     } else {
diff --git a/src/Hybrid/MCHybrid/MCHybridSOG.cpp b/src/Hybrid/MCHybrid/MCHybridSOG.cpp
index 121d3645b27362345f27ab67ced29f5cf1e09622..524f02905e8e45eb402c724d15a8183f74da8898 100644
--- a/src/Hybrid/MCHybrid/MCHybridSOG.cpp
+++ b/src/Hybrid/MCHybrid/MCHybridSOG.cpp
@@ -385,7 +385,7 @@ void MCHybridSOG::computeDSOG(LDDGraph &g) {
     m_nbsend = 0;
     m_gc = 0;
 
-    for (uint8_t i = 0; i < m_nb_thread - 1; i++) {
+    for (uint8_t i = 0; i < m_nb_thread - 1; ++i) {
         m_list_thread[i] = new thread(threadHandler, this);
         if (m_list_thread[i] == nullptr) {
             cout << "error: thread creation failed..." << endl;
@@ -411,8 +411,8 @@ MDD MCHybridSOG::decodage_message(const char *chaine) {
     //nb_marq = (nb_marq << 7) | ((unsigned char) chaine[0] >> 1);
     unsigned int index = 2;
     uint32_t list_marq[m_nbPlaces];
-    for (unsigned int i = 0; i < nb_marq; i++) {
-        for (unsigned int j = 0; j < m_nbPlaces; j++) {
+    for (unsigned int i = 0; i < nb_marq; ++i) {
+        for (unsigned int j = 0; j < m_nbPlaces; ++j) {
             list_marq[j] = (uint32_t) ((unsigned char) chaine[index] - 1);
             index++;
         }
@@ -462,7 +462,7 @@ void MCHybridSOG::sendPropToMC(size_t pos) {
     size_t indice = 8;
     memcpy(mess_to_send + indice, &s_mp, 2);
     indice += 2;
-    for (auto it = marked_places.begin(); it != marked_places.end(); it++) {
+    for (auto it = marked_places.begin(); it != marked_places.end();++it) {
         memcpy(mess_to_send + indice, &(*it), 2);
         indice += 2;
     }
diff --git a/src/Hybrid/MCHybridReq/MCHybridSOGReq.cpp b/src/Hybrid/MCHybridReq/MCHybridSOGReq.cpp
index 7bbd91e84fc736288487fbef7334b8ba8e3e2229..1d5685103ba1130e3f1614948bed3172b86bb570 100644
--- a/src/Hybrid/MCHybridReq/MCHybridSOGReq.cpp
+++ b/src/Hybrid/MCHybridReq/MCHybridSOGReq.cpp
@@ -22,7 +22,7 @@
 #define REDUCE 1
 using namespace std;
 
-MCHybridSOGReq::MCHybridSOGReq(const NewNet &R, MPI_Comm &comm_world, bool init):m_comm_world(comm_world) {
+MCHybridSOGReq::MCHybridSOGReq(const NewNet &R, MPI_Comm &comm_world, bool init): m_comm_world(comm_world) {
     initializeLDD();
     m_net = &R;
     m_init = init;
diff --git a/src/Hybrid/MCHybridReq/MCHybridSOGReq.h b/src/Hybrid/MCHybridReq/MCHybridSOGReq.h
index c5c8bbaf08288d0de5701957360ab48eae0c127d..e4862fcc760229c43ca84d67b6feace76523d171 100644
--- a/src/Hybrid/MCHybridReq/MCHybridSOGReq.h
+++ b/src/Hybrid/MCHybridReq/MCHybridSOGReq.h
@@ -52,14 +52,13 @@ class MCHybridSOGReq : public CommonSOG
 {
 public:
     MCHybridSOGReq(const NewNet &, MPI_Comm &, bool init = false);
-    void buildFromNet(int index);
     /// principal functions to construct the SOG
-    void computeDSOG(LDDGraph &g);
+    void computeDSOG(LDDGraph &g) override;
     ~MCHybridSOGReq() override;
     static void *threadHandler(void *context);
-    void *doCompute();
+    virtual void *doCompute();
+
 protected:
-private:
     std::condition_variable m_condStack;
     mutable std::mutex m_mutexCond;
     MPI_Comm m_comm_world;
diff --git a/src/Hybrid/MCHybridReqPOR/MCHybridSOGReqPOR.cpp b/src/Hybrid/MCHybridReqPOR/MCHybridSOGReqPOR.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b17834993a34f5a3c624ab6b13db8365798e80c1
--- /dev/null
+++ b/src/Hybrid/MCHybridReqPOR/MCHybridSOGReqPOR.cpp
@@ -0,0 +1,225 @@
+#include "MCHybridSOGReqPOR.h"
+//#define DEBUG_GC
+
+#include <cstdio>
+#include <openssl/md5.h>
+#include "misc/md5_hash.h"
+
+#define LENGTH_ID 16
+//#define LENGTH_MSG 180
+#define TAG_STATE 1
+#define TAG_FINISH 2
+#define TAG_INITIAL 3
+#define TAG_ASK_SUCC 4
+
+
+#define TAG_ACK_INITIAL 8
+#define TAG_ASK_STATE 9
+#define TAG_ACK_STATE 10
+#define TAG_ACK_SUCC 11
+
+//#define DEBUG_GC 1
+#define REDUCE 1
+using namespace std;
+
+MCHybridSOGReqPOR::MCHybridSOGReqPOR(const NewNet &R, MPI_Comm &comm_world, bool init):MCHybridSOGReq(R,comm_world,init) {
+
+}
+
+void *MCHybridSOGReqPOR::doCompute() {
+
+    int id_thread;
+    id_thread = m_id_thread++;
+    unsigned char Identif[20];
+    m_Terminated = false;
+    Set fireObs;
+    bool _div,_dead;
+    /****************************************** initial state ********************************************/
+    if (task_id == 0 && id_thread == 0) {
+        string *chaine = new string();
+        LDDState *c = new LDDState;
+        MDD Complete_meta_state=saturatePOR(m_initialMarking,fireObs,_div,_dead);
+        c->m_lddstate = Complete_meta_state;
+        SylvanWrapper::convert_wholemdd_stringcpp(Complete_meta_state, *chaine);
+        md5_hash::compute(*chaine, Identif);
+        auto destination = (uint16_t) (Identif[0] % n_tasks);
+        c->setProcess(destination);
+        if (destination == 0) {
+            m_nbmetastate++;
+            m_graph->setInitialState(c);
+            m_graph->insert(c);
+            memcpy(c->m_SHA2, Identif, 16);
+            m_common_stack.push(Pair(couple(c, Complete_meta_state), fireObs));
+            m_condStack.notify_one();
+
+        } else {
+            MDD initialstate = Complete_meta_state;
+            m_graph->insertSHA(c);
+            memcpy(c->m_SHA2, Identif, 16);
+            //initialstate = Complete_meta_state;
+            SylvanWrapper::convert_wholemdd_stringcpp(initialstate, *chaine);
+            m_tosend_msg.push(MSG(chaine, destination));
+        }
+    }
+    /******************************* envoie et reception des aggregats ************************************/
+    string chaine;
+    if (id_thread == 0) {
+        do {
+            send_state_message();
+            read_message();
+            if (m_waitingBuildSucc == statereq::waitingBuild) {
+                bool res;
+                size_t pos = m_graph->findSHAPos(m_id_md5, res);
+                if (res) {
+                    m_waitingBuildSucc = statereq::waitingSucc;
+                    m_aggWaiting = m_graph->getLDDStateById(pos);
+                }
+            }
+            if (m_waitingBuildSucc == statereq::waitingSucc) {
+                if (m_aggWaiting->isCompletedSucc()) {
+                    m_waitingBuildSucc = statereq::waitInitial;
+                    sendSuccToMC();
+                }
+            }
+            if (m_waitingAgregate) {
+                bool res = false;
+                size_t pos = m_graph->findSHAPos(m_id_md5, res);
+                if (res) {
+                    m_waitingAgregate = false;
+                    sendPropToMC(pos);
+                }
+            }
+
+        } while (!m_Terminated);
+
+    }
+        /******************************* Construction des aggregats ************************************/
+
+    else {
+        while (!m_Terminated) {
+            {
+                std::unique_lock lk(m_mutexCond);
+                m_condStack.wait(lk,
+                                 [this] { return !m_common_stack.empty() || !m_received_msg.empty() || m_Terminated; });
+            }
+            /*if ( id_thread>1 ) {
+                if ( ++m_gc==1 ) {
+                    m_gc_mutex.lock();
+                }
+            }*/
+            if (!m_Terminated) {
+                Pair e;
+                if (m_common_stack.try_pop(e)) {
+                    while (!e.second.empty() && !m_Terminated) {
+                        int t = *(e.second.begin());
+                        e.second.erase(t);
+                        MDD ldd_reachedclass=saturatePOR(get_successor(e.first.second, t),fireObs,_div,_dead);
+                        string *message_to_send1 = new string();
+                        SylvanWrapper::convert_wholemdd_stringcpp(ldd_reachedclass, *message_to_send1);
+                        md5_hash::compute(*message_to_send1, Identif);
+                        uint16_t destination = (uint16_t) (Identif[0] % n_tasks);
+                        /**************** construction local ******/
+                        if (destination == task_id) {
+                            bool res = false;
+                            LDDState *pos = m_graph->insertFindByMDD(ldd_reachedclass, res);
+                            if (!res) {
+                                pos->setProcess(task_id);
+                                pos->setDiv(Set_Div(ldd_reachedclass));
+                                pos->setDeadLock(_dead);
+                                memcpy(pos->m_SHA2, Identif, 16);
+                                m_common_stack.push(Pair(couple(pos, pos->m_lddstate), fireObs));
+                                m_condStack.notify_one();
+                            }
+                            m_graph->addArc();
+                            {
+                                std::scoped_lock<std::mutex> guard(m_graph_mutex);
+                                e.first.first->Successors.insert(e.first.first->Successors.begin(),
+                                                                 LDDEdge(pos, t));
+                                pos->Predecessors.insert(pos->Predecessors.begin(), LDDEdge(e.first.first, t));
+                            }
+                        }
+                            /**************** construction externe ******/
+                        else { // send to another process
+                            LDDState *reached_class = new LDDState;
+                            reached_class->m_lddstate = ldd_reachedclass;
+                            reached_class->setProcess(destination);
+                            LDDState *posV = m_graph->insertFindSha(Identif, reached_class);
+                            if (!posV) {
+                                MDD reached{ldd_reachedclass};
+                                string *message_to_send2 = new string();
+                                SylvanWrapper::convert_wholemdd_stringcpp(reached, *message_to_send2);
+                                m_graph->addArc();
+                                m_graph_mutex.lock();
+                                e.first.first->Successors.insert(e.first.first->Successors.begin(),
+                                                                 LDDEdge(reached_class, t));
+                                reached_class->Predecessors.insert(reached_class->Predecessors.begin(),
+                                                                   LDDEdge(e.first.first, t));
+                                m_graph_mutex.unlock();
+                                m_tosend_msg.push(MSG(message_to_send2, destination));
+
+                            } else {
+                                //cout<<"sha found "<<endl;
+                                m_graph->addArc();
+                                {
+                                    std::scoped_lock<std::mutex> guard(m_graph_mutex);
+                                    e.first.first->Successors.insert(e.first.first->Successors.begin(),
+                                                                     LDDEdge(posV, t));
+                                    posV->Predecessors.insert(posV->Predecessors.begin(), LDDEdge(e.first.first, t));
+                                }
+                                delete reached_class;
+                            }
+                        }
+                    }
+                    e.first.first->setCompletedSucc();
+                }
+
+                /******************************* Construction des aggregats � partir de pile de messages ************************************/
+                MSG popped_msg;
+                if (m_received_msg.try_pop(popped_msg)) {
+                    MDD receivedLDD = decodage_message(popped_msg.first->c_str());
+                    delete popped_msg.first;
+                    MDD MState =saturatePOR(receivedLDD,fireObs,_div,_dead);
+                    bool res = false;
+                    LDDState *Agregate = m_graph->insertFindByMDD(MState, res);
+                    if (!res) {
+                        Agregate->setDiv(Set_Div(MState));
+                        Agregate->setDeadLock(_dead);
+                        Agregate->setProcess(task_id);
+                        SylvanWrapper::convert_wholemdd_stringcpp(MState, chaine);
+                        md5_hash::compute(chaine, Identif);
+                        memcpy(Agregate->m_SHA2, Identif, 16);
+                        m_common_stack.push(Pair(couple(Agregate, MState), fireObs));
+                        m_condStack.notify_one();
+                    }
+                }
+
+                /*    if ( id_thread>1 ) {
+                        if ( --m_gc==0 ) {
+                            m_gc_mutex.unlock();
+                        }
+
+                    }*/
+                // }
+
+            }
+        }    /// End else
+
+        // cout<<"Working process "<<task_id<<" leaved...thread "<<id_thread<<endl;
+
+    }
+
+    //  cout<<"Finnnnnn...."<<endl;
+}
+
+
+
+
+
+
+
+
+
+
+MCHybridSOGReqPOR::~MCHybridSOGReqPOR() = default;
+
+
diff --git a/src/Hybrid/MCHybridReqPOR/MCHybridSOGReqPOR.h b/src/Hybrid/MCHybridReqPOR/MCHybridSOGReqPOR.h
new file mode 100644
index 0000000000000000000000000000000000000000..ddcce78a2aa104882b3b3320f1fc71f079f759fa
--- /dev/null
+++ b/src/Hybrid/MCHybridReqPOR/MCHybridSOGReqPOR.h
@@ -0,0 +1,55 @@
+#ifndef MCHybridSOGReqPOR_H
+#define MCHybridSOGReqPOR_H
+
+#include <stack>
+#include <vector>
+#include "NewNet.h"
+#include <pthread.h>
+#include <cstdio>
+#include <sys/types.h>
+#include <unistd.h>
+#include "LDDGraph.h"
+#include "TransSylvan.h"
+
+#include <mpi.h>
+#include <misc/sha2.h>
+
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#include <sys/types.h>
+#include <cstdlib>
+#include <sstream>
+
+#include <iostream>
+#include <queue>
+#include <string>
+#include <ctime>
+#include <chrono>
+#include "CommonSOG.h"
+#include <atomic>
+#include <thread>
+#include <mutex>
+#include <condition_variable>
+#include "misc/SafeDequeue.h"
+#include "../MCHybridReq/MCHybridSOGReq.h"
+// namespace mpi = boost::mpi;
+//#define MASTER 0
+//#define large 128
+extern unsigned int nb_th;
+extern int n_tasks, task_id;
+
+
+
+typedef pair<string *, unsigned int> MSG;
+
+typedef stack<MSG> pile_msg;
+
+class MCHybridSOGReqPOR : public MCHybridSOGReq
+{
+public:
+    MCHybridSOGReqPOR(const NewNet &, MPI_Comm &, bool init = false);
+    ~MCHybridSOGReqPOR() override;
+    void *doCompute() override;
+};
+
+#endif  // MCHybridSOGReqPOR_H
diff --git a/src/LDDGraph.cpp b/src/LDDGraph.cpp
index f4267e68f4928936d82f9182373012fca800a1e7..8a3964b7eac9e802df51e6935851cd1704cc0018 100644
--- a/src/LDDGraph.cpp
+++ b/src/LDDGraph.cpp
@@ -133,11 +133,11 @@ void LDDGraph::printCompleteInformation() {
 void LDDGraph::InitVisit(LDDState *S, size_t nb) {
     if (nb <= m_nbStates) {
 
-        for (LDDEdges::const_iterator i = S->Successors.begin(); !(i == S->Successors.end()); i++) {
+        for (const auto & i : S->Successors) {
 
-            if ((*i).first->isVisited() == true) {
+            if (i.first->isVisited() == true) {
                 nb++;
-                InitVisit((*i).first, nb);
+                InitVisit(i.first, nb);
             }
         }
 
@@ -152,10 +152,10 @@ void LDDGraph::printGraph(LDDState *s, size_t &nb) {
 
         s->setVisited();
         LDDEdges::const_iterator i;
-        for (i = s->Successors.begin(); !(i == s->Successors.end()); i++) {
-            if ((*i).first->isVisited() == false) {
+        for (const auto & i:  s->Successors) {
+            if (i.first->isVisited() == false) {
                 nb++;
-                printGraph((*i).first, nb);
+                printGraph(i.first, nb);
             }
         }
 
@@ -165,12 +165,19 @@ void LDDGraph::printGraph(LDDState *s, size_t &nb) {
 
 
 /*** Giving a position in m_GONodes Returns an LDDState ****/
-LDDState *LDDGraph::getLDDStateById(unsigned int id) {
+LDDState *LDDGraph::getLDDStateById(const unsigned int& id) {
     return m_GONodes.at(id);
 }
 
 string_view LDDGraph::getTransition(uint16_t pos) {
 
+    /*for (const auto & it : m_transition) {
+        if (it.second == pos) {
+            return it.first;
+        }
+    }
+    return it.first;*/
+
     map<string, uint16_t>::iterator it = m_transition->begin();
 
     while (it != m_transition->end()) {
diff --git a/src/LDDGraph.h b/src/LDDGraph.h
index 58546561806f41338d8cca03f811bbc67070aea4..3fd9c12ae637fcedd019cea46d42ec408c641fa8 100755
--- a/src/LDDGraph.h
+++ b/src/LDDGraph.h
@@ -28,7 +28,7 @@ class LDDGraph
         void setPlace(map<uint16_t,string>& list_places);
         void setTransition(map<string,uint16_t>& list_transitions);
         MetaLDDNodes m_GONodes;
-        LDDState *getLDDStateById(unsigned int id);
+        LDDState *getLDDStateById(const unsigned int& id);
 		LDDState *m_initialstate=nullptr;
         uint64_t m_nbStates;
 		uint64_t m_nbMarking;
diff --git a/src/LDDState.cpp b/src/LDDState.cpp
index b92653a9f4a45ea3f00fc5abce013970832fa99a..5ea514e90eefb1e508f669c8e4d3e341b51c1eda 100644
--- a/src/LDDState.cpp
+++ b/src/LDDState.cpp
@@ -5,7 +5,7 @@
 
 LDDState::~LDDState()=default;
 
-void LDDState::setLDDValue(MDD m) {
+void LDDState::setLDDValue(const MDD & m) {
     m_lddstate=m;
 }
 MDD  LDDState::getLDDValue() {
diff --git a/src/LDDState.h b/src/LDDState.h
index d9c448099af63c05e938ebd0538800c51dd82854..cabe5fa0b6298d449b1b374ca4856b24016f1931 100755
--- a/src/LDDState.h
+++ b/src/LDDState.h
@@ -22,7 +22,7 @@ class LDDState {
   vector<pair<LDDState*, int>>* getSuccessors();
   vector<pair<LDDState*, int> > Predecessors, Successors;
 
-  void setLDDValue(MDD m);
+  void setLDDValue(const MDD& m);
   MDD getLDDValue();
   MDD m_lddstate=0;
   unsigned char m_SHA2[81];
@@ -31,9 +31,9 @@ class LDDState {
   bool m_blocage=false;
   bool isVirtual() {return m_virtual;}
   void setVirtual(){m_virtual=true;}
-  void setDiv(bool di) {m_boucle=di;}
+  void setDiv(const bool& di) {m_boucle=di;}
   inline bool isDiv() {return m_boucle;}
-  void setDeadLock(bool de) {m_blocage=de;}
+  void setDeadLock(const bool& de) {m_blocage=de;}
   bool isDeadLock() {return m_blocage;}
   inline void setVisited() {m_visited=true;}
   [[nodiscard]] inline bool isVisited() const {return m_visited;}
@@ -41,7 +41,7 @@ class LDDState {
   bool isCompletedSucc() {return m_completed;}
   vector<uint16_t> getMarkedPlaces(set<uint16_t>& lplacesAP);
   vector<uint16_t> getUnmarkedPlaces(set<uint16_t>& lplacesAP);
-  void setProcess(uint16_t v) {m_process=v;}
+  void setProcess(const uint16_t& v) {m_process=v;}
   [[nodiscard]] uint16_t getProcess() const {return m_process;}
   inline void decNbSuccessors() {m_nbSuccessorsToBeProcessed--;}
  protected:
diff --git a/src/MCMultiCore/MCCPPThPor.cpp b/src/MCMultiCore/MCCPPThPor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..954f66bce72cd44b70d60ea278f9322917091f8f
--- /dev/null
+++ b/src/MCMultiCore/MCCPPThPor.cpp
@@ -0,0 +1,108 @@
+#include "MCCPPThPor.h"
+//#include "sylvan.h"
+//#include <sylvan_int.h>
+#include <functional>
+#include <iostream>
+
+
+#include "SylvanWrapper.h"
+
+#define GETNODE(mdd) ((mddnode_t)llmsset_index_to_ptr(nodes, mdd))
+
+using namespace std;
+
+MCCPPThPor::MCCPPThPor(const NewNet &R, int nbThread) :
+        ModelCheckBaseMT(R, nbThread) {
+}
+
+
+void MCCPPThPor::preConfigure() {
+    initializeLDD();
+    loadNetFromFile();
+    ComputeTh_Succ();
+}
+
+/*
+ * Compute SOG with POR reduction
+ */
+void MCCPPThPor::Compute_successors() {
+    uint16_t id_thread;
+    id_thread=m_id_thread++;
+    Set fireObs;
+    bool _div,_dead;
+    if (id_thread == 0) {
+        auto *initialNode = new LDDState;
+        initialNode->m_lddstate=saturatePOR(m_initialMarking,fireObs,_div,_dead);
+        //initialNode->setDiv(_div);
+        initialNode->setDiv(Set_Div(initialNode->m_lddstate));
+        initialNode->setDeadLock(_dead);
+        m_graph->setInitialState(initialNode);
+        m_graph->insert(initialNode);
+        m_common_stack.push(Pair(couple(initialNode, initialNode->m_lddstate), fireObs));
+        m_condStack.notify_one();
+        m_finish_initial = true;
+    }
+
+    Pair e;
+    do {
+        std::unique_lock<std::mutex> lk(m_mutexStack);
+        m_condStack.wait(lk, std::bind(&MCCPPThPor::hasToProcess, this));
+        lk.unlock();
+        if (m_common_stack.try_pop(e) && !m_finish) {
+            while (!e.second.empty() && !m_finish) {
+                int t = *e.second.begin();
+                e.second.erase(t);
+                MDD reducedMS = saturatePOR(get_successor(e.first.second, t),fireObs,_div,_dead);
+                SylvanWrapper::lddmc_refs_push(reducedMS);
+                bool res;
+                LDDState *pos = m_graph->insertFindByMDD(reducedMS, res);
+                m_graph->addArc();
+                if (!res) {
+                    pos->setDeadLock(_dead);
+                    //pos->setDiv(Set_Div(pos->m_lddstate));
+                    pos->setDiv(_div);
+                    m_common_stack.push(Pair(couple(pos, reducedMS), fireObs));
+                    m_condStack.notify_one();
+                }
+                m_graph_mutex.lock();
+                e.first.first->Successors.insert(e.first.first->Successors.begin(), LDDEdge(pos, t));
+                pos->Predecessors.insert(pos->Predecessors.begin(), LDDEdge(e.first.first, t));
+                m_graph_mutex.unlock();
+            }
+            e.first.first->setCompletedSucc();
+            m_condBuild.notify_one();
+        } //end advance
+
+    } while (!m_finish);
+}
+
+
+void MCCPPThPor::threadHandler(void *context) {
+    SylvanWrapper::lddmc_refs_init();
+    ((MCCPPThPor *) context)->Compute_successors();
+}
+
+void MCCPPThPor::ComputeTh_Succ() {
+    m_id_thread = 0;
+    pthread_barrier_init(&m_barrier_builder, nullptr, m_nb_thread + 1);
+    m_finish = false;
+    for (int i = 0; i < m_nb_thread; i++) {
+        m_list_thread[i] = new thread(threadHandler, this);
+        if (m_list_thread[i] == nullptr) {
+            cout << "error: pthread creation failed. "  << endl;
+        }
+    }
+}
+
+MCCPPThPor::~MCCPPThPor() {
+    m_finish = true;
+    m_condStack.notify_all();
+    for (int i = 0; i < m_nb_thread; i++) {
+        m_list_thread[i]->join();
+        delete m_list_thread[i];
+    }
+}
+
+bool MCCPPThPor::hasToProcess() const {
+    return m_finish || !m_common_stack.empty();
+}
diff --git a/src/MCMultiCore/MCCPPThPor.h b/src/MCMultiCore/MCCPPThPor.h
new file mode 100644
index 0000000000000000000000000000000000000000..89b9830ba01dd7b41d9045c484ddceb25a7358e8
--- /dev/null
+++ b/src/MCMultiCore/MCCPPThPor.h
@@ -0,0 +1,34 @@
+#ifndef MCCPPThPor_H
+#define MCCPPThPor_H
+#include "ModelCheckBaseMT.h"
+#include "misc/stacksafe.h"
+#include "misc/SafeDequeue.h"
+#include <atomic>
+#include <thread>
+#include <mutex>
+#include <condition_variable>
+typedef pair<LDDState *, int> couple_th;
+
+/*
+ * Multi-threading with C++14 Library
+ */
+class MCCPPThPor : public ModelCheckBaseMT
+{
+public:
+    MCCPPThPor(const NewNet &R,int nbThread);
+    ~MCCPPThPor();
+    static void threadHandler(void *context);
+    void Compute_successors();
+    void ComputeTh_Succ();
+private:
+    void preConfigure();
+    bool hasToProcess() const;
+
+    SafeDequeue<Pair> m_common_stack;       
+    atomic<uint8_t> m_id_thread;
+    pthread_barrier_t m_barrier_builder;
+    std::condition_variable m_condStack;
+    std::mutex m_mutexStack;
+    thread* m_list_thread[128];    
+};
+#endif
diff --git a/src/MCMultiCore/MCThReqPor.cpp b/src/MCMultiCore/MCThReqPor.cpp
index 62d34c40cd4e12d5bc6f2516ada32eda0f4c3309..bd2d1d31932049aa27ed87587dfd7cc3acd505f3 100644
--- a/src/MCMultiCore/MCThReqPor.cpp
+++ b/src/MCMultiCore/MCThReqPor.cpp
@@ -21,7 +21,7 @@ void MCThReqPor::ComputeTh_Succ() {
     m_id_thread = 0;
     //cout<<"Enter : "<<__func__ <<endl;
     pthread_barrier_init(&m_barrier_threads, nullptr, m_nb_thread + 1);
-    for (int i = 0; i < m_nb_thread; i++) {
+    for (int i = 0; i < m_nb_thread; ++i) {
         m_list_thread[i] = new thread(threadHandler, this);
         if (m_list_thread[i] == nullptr) {
             cout << "error: pthread creation failed" << endl;
@@ -71,7 +71,7 @@ void MCThReqPor::buildSucc(LDDState *agregate) {
     if (!agregate->isVisited()) {
         agregate->setVisited();
         if (agregate->getMCurrentLevel() == 0) {
-            Set fire = firable_obs(agregate->m_lddstate);
+            Set fire = firable_obs(agregate->m_lddstate);///////////////////////////////////////////////////
             agregate->setMCurrentLevel(LEVEL);
             agregate->m_nbSuccessorsToBeProcessed = fire.size();
             if (!fire.empty()) {
diff --git a/src/MCMultiCore/ModelCheckerCPPThread.cpp b/src/MCMultiCore/ModelCheckerCPPThread.cpp
index 58d4addbf22916de4610f61751aca93539abdcc1..bffe8d5ead5d45aba5db91fd9e7d4f7c2e364eb3 100644
--- a/src/MCMultiCore/ModelCheckerCPPThread.cpp
+++ b/src/MCMultiCore/ModelCheckerCPPThread.cpp
@@ -28,58 +28,6 @@ void ModelCheckerCPPThread::preConfigure() {
     ComputeTh_Succ();
 }
 
-/*
- * Compute SOG with POR reduction
- */
-void ModelCheckerCPPThread::ComputeSuccessorsPOR() {
-    uint16_t id_thread;
-    id_thread=m_id_thread++;
-    Set fireObs;
-    bool _div,_dead;
-    if (id_thread == 0) {
-        auto *initialNode = new LDDState;
-        initialNode->m_lddstate=saturatePOR(m_initialMarking,fireObs,_div,_dead);
-        initialNode->setDiv(_div);
-        initialNode->setDeadLock(_dead);
-        m_graph->setInitialState(initialNode);
-        m_graph->insert(initialNode);
-        m_common_stack.push(Pair(couple(initialNode, initialNode->m_lddstate), fireObs));
-        m_condStack.notify_one();
-        m_finish_initial = true;
-    }
-
-    Pair e;
-    do {
-        std::unique_lock<std::mutex> lk(m_mutexStack);
-        m_condStack.wait(lk, std::bind(&ModelCheckerCPPThread::hasToProcess, this));
-        lk.unlock();
-        if (m_common_stack.try_pop(e) && !m_finish) {
-            while (!e.second.empty() && !m_finish) {
-                int t = *e.second.begin();
-                e.second.erase(t);
-                MDD reducedMS = saturatePOR(get_successor(e.first.second, t),fireObs,_div,_dead);
-                SylvanWrapper::lddmc_refs_push(reducedMS);
-                bool res;
-                LDDState *pos = m_graph->insertFindByMDD(reducedMS, res);
-                m_graph->addArc();
-                if (!res) {
-
-                    pos->setDeadLock(_dead);
-                    pos->setDiv(_div);
-                    m_common_stack.push(Pair(couple(pos, reducedMS), fireObs));
-                    m_condStack.notify_one();
-                }
-                m_graph_mutex.lock();
-                e.first.first->Successors.insert(e.first.first->Successors.begin(), LDDEdge(pos, t));
-                pos->Predecessors.insert(pos->Predecessors.begin(), LDDEdge(e.first.first, t));
-                m_graph_mutex.unlock();
-            }
-            e.first.first->setCompletedSucc();
-            m_condBuild.notify_one();
-        } //end advance
-
-    } while (!m_finish);
-}
 /*
  * Compute SOG without reduction
  */
diff --git a/src/MCMultiCore/ModelCheckerCPPThread.h b/src/MCMultiCore/ModelCheckerCPPThread.h
index c69bd88fa12e27b67c736577e926aadf84ca01df..c3ddbf0540c58873e6048168d15464a613fd4e08 100644
--- a/src/MCMultiCore/ModelCheckerCPPThread.h
+++ b/src/MCMultiCore/ModelCheckerCPPThread.h
@@ -19,7 +19,6 @@ public:
     ~ModelCheckerCPPThread();
     static void threadHandler(void *context);
     void Compute_successors();
-    void ComputeSuccessorsPOR();
     void ComputeTh_Succ();
 private:
     void preConfigure();
@@ -27,7 +26,7 @@ private:
 
     SafeDequeue<Pair> m_common_stack;       
     atomic<uint8_t> m_id_thread;
-    std::mutex m_mutex; 
+    //std::mutex m_mutex;
     pthread_barrier_t m_barrier_builder;
     std::condition_variable m_condStack;
     std::mutex m_mutexStack;
diff --git a/src/SogKripkeTh.cpp b/src/SogKripkeTh.cpp
index 7391a23938268f0bbbc980baff00133c7b90f650..f2481bd9ae224d9f3974c1fb57ba115b8834f5d4 100644
--- a/src/SogKripkeTh.cpp
+++ b/src/SogKripkeTh.cpp
@@ -27,11 +27,11 @@ SogKripkeTh::SogKripkeTh(const bdd_dict_ptr &dict_ptr,ModelCheckBaseMT *builder)
 
 SogKripkeTh::SogKripkeTh(const spot::bdd_dict_ptr& dict_ptr,ModelCheckBaseMT *builder,set<string> &l_transap,set<string> &l_placeap):SogKripkeTh(dict_ptr,builder) {
 
-    for (auto it=l_transap.begin();it!=l_transap.end();it++) {
-        register_ap(*it);
+    for (const auto& it:l_transap) {
+        register_ap(it);
     }
-    for (auto it=l_placeap.begin();it!=l_placeap.end();it++)
-        register_ap(*it);
+    for (const auto & it: l_placeap)
+        register_ap(it);
 
 }
 
@@ -53,32 +53,14 @@ std::string SogKripkeTh::format_state(const spot::state* s) const
   }
 
 SogKripkeIteratorTh* SogKripkeTh::succ_iter(const spot::state* s) const {
-   
     auto ss = static_cast<const SogKripkeStateTh*>(s);
     LDDState *aggregate=ss->getLDDState();
     bdd cond = state_condition(ss);
-    /*if (iter_cache_)
-    {
-      auto it = static_cast<SogKripkeIteratorTh*>(iter_cache_);
-      it->recycle(aggregate, cond);
-      iter_cache_ = nullptr;    // empty the cache
-      return it;
-    }*/
-
-  return new SogKripkeIteratorTh(aggregate,cond);
-
-    
-    
-    
-/*    auto ss = static_cast<const SogKripkeStateTh*>(s);
-   //////////////////////////////////////////////
-
-    return new SogKripkeIteratorTh(ss->getLDDState(),state_condition(ss));//,b);//s state_condition(ss));*/
+    return new SogKripkeIteratorTh(aggregate,cond);
 }
 
 bdd SogKripkeTh::state_condition(const spot::state* s) const
   {
-
     auto ss = static_cast<const SogKripkeStateTh*>(s);
 	vector<uint16_t> marked_place = ss->getLDDState()->getMarkedPlaces(m_builder->getPlaceProposition());
 #ifdef TESTENABLE
@@ -88,21 +70,20 @@ bdd SogKripkeTh::state_condition(const spot::state* s) const
 #endif
     bdd result=bddtrue;
     // Marked places
-    for (auto it=marked_place.begin();it!=marked_place.end();it++) {
-        string name=string(m_builder->getPlace(*it));
+    for (const auto& it:marked_place) {
+        string name=string(m_builder->getPlace(it));
         spot::formula f=spot::formula::ap(name);
         result&=bdd_ithvar((dict_->var_map.find(f))->second);
     }
     vector<uint16_t> unmarked_place=ss->getLDDState()->getUnmarkedPlaces(m_builder->getPlaceProposition());
-    for (auto it=unmarked_place.begin();it!=unmarked_place.end();it++) {
-        string name=string(m_builder->getPlace(*it));
+    for (const auto& it: unmarked_place) {
+        string name=string(m_builder->getPlace(it));
         spot::formula f=spot::formula::ap(name);
         result&=!bdd_ithvar((dict_->var_map.find(f))->second);
     }
   return result;
   }
 
-
 SogKripkeTh::~SogKripkeTh()
 {
     //dtor
diff --git a/src/SpotSogIterator.cpp b/src/SpotSogIterator.cpp
index ae61c6374b317de2060b94026dcbfdeb644b8d7f..240ccf719566697b72c2c07d4a09345429200aa0 100644
--- a/src/SpotSogIterator.cpp
+++ b/src/SpotSogIterator.cpp
@@ -9,7 +9,7 @@ SpotSogIterator::SpotSogIterator(const LDDState* lddstate):m_lddstate(lddstate)
     //vector<pair<LDDState*, int>>
 
     m_lddstate->setDiv(true);
-    for (int i=0;i<m_lddstate->getSuccessors()->size();i++) {
+    for (int i=0;i<m_lddstate->getSuccessors()->size();++i) {
         m_lsucc.push_back(m_lddstate->getSuccessors()->at(i));
     }
    /* if (lddstate->isDeadLock()) {
diff --git a/src/SylvanWrapper.cpp b/src/SylvanWrapper.cpp
index 569932e49d1805890626938908cd87ce6dd951c9..5c64e27ebb93aa82b4169c60c2218d009f924c7f 100644
--- a/src/SylvanWrapper.cpp
+++ b/src/SylvanWrapper.cpp
@@ -478,7 +478,7 @@ SylvanWrapper::llmsset_lookup2(const llmsset2_t dbs, uint64_t a, uint64_t b, int
     }
 }
 
-uint64_t SylvanWrapper::llmsset_lookup(const llmsset2_t dbs, const uint64_t a, const uint64_t b, int *created) {
+uint64_t SylvanWrapper::llmsset_lookup(const llmsset2_t& dbs, const uint64_t& a, const uint64_t& b, int *created) {
     return llmsset_lookup2(dbs, a, b, created, 0);
 }
 
@@ -603,7 +603,7 @@ size_t SylvanWrapper::lddmc_nodecount_mark(MDD mdd) {
     return 1 + lddmc_nodecount_mark(mddnode_getdown(n)) + lddmc_nodecount_mark(mddnode_getright(n));
 }
 
-MDD SylvanWrapper::lddmc_union_mono(MDD a, MDD b) {
+MDD SylvanWrapper::lddmc_union_mono(MDD a,MDD b) {
     /* Terminal cases */
     if (a == b) return a;
     if (a == lddmc_false) return b;
@@ -834,10 +834,10 @@ bool SylvanWrapper::isFirable(MDD cmark, MDD minus) {
     return result;
 }
 
-MDD SylvanWrapper::lddmc_firing_mono(MDD cmark, const MDD minus, const MDD plus) {
+MDD SylvanWrapper::lddmc_firing_mono(MDD cmark, const MDD& minus, const MDD& plus) {
     // for an empty set of source states, or an empty transition relation, return the empty set
     if (cmark == lddmc_true) return lddmc_true;
-    if (minus == lddmc_false || plus == lddmc_false) return lddmc_false;
+    if (minus == lddmc_false || plus == lddmc_false || cmark==lddmc_false) return lddmc_false;
 
     MDD result;
     MDD _cmark = cmark, _minus = minus, _plus = plus;
@@ -1192,7 +1192,7 @@ int SylvanWrapper::llmsset_mark(const llmsset2_t dbs, uint64_t index) {
  * Intersection
  */
 
-MDD SylvanWrapper::lddmc_intersect(MDD a, MDD b) {
+MDD SylvanWrapper::lddmc_intersect(MDD a,MDD b) {
 /* Terminal cases */
     if (a == b) return a;
     if (a == lddmc_false || b == lddmc_false) return lddmc_false;
diff --git a/src/SylvanWrapper.h b/src/SylvanWrapper.h
index a1ad54c4e0bc27a6af0d3fcf53150183eba212d3..e3afa4905bf7dbacc9a904aea8430c402dc8a23b 100644
--- a/src/SylvanWrapper.h
+++ b/src/SylvanWrapper.h
@@ -173,7 +173,7 @@ public:
 
     static size_t lddmc_nodecount(MDD mdd);
 
-    static MDD lddmc_union_mono(MDD a, MDD b);
+    static MDD lddmc_union_mono(MDD a,MDD b);
     static MDD lddmc_intersect(MDD a, MDD b);
     static bool isSingleMDD(MDD mdd);
 
@@ -185,7 +185,7 @@ public:
 
     static MDD ldd_minus(MDD a, MDD b);
 
-    static MDD lddmc_firing_mono(MDD cmark, const MDD minus, const MDD plus);
+    static MDD lddmc_firing_mono(MDD cmark, const MDD& minus, const MDD& plus);
 
     static size_t lddmc_nodecount_mark(MDD mdd);
 
@@ -227,7 +227,7 @@ public:
     static inline uint64_t
     llmsset_lookup2(const llmsset2_t dbs, uint64_t a, uint64_t b, int *created, const int custom);
 
-    static uint64_t llmsset_lookup(const llmsset2_t dbs, const uint64_t a, const uint64_t b, int *created);
+    static uint64_t llmsset_lookup(const llmsset2_t& dbs, const uint64_t& a, const uint64_t& b, int *created);
 
     static uint64_t llmsset_hash(const uint64_t a, const uint64_t b, const uint64_t seed);
 
diff --git a/src/main.cpp b/src/main.cpp
index ff38313d3c08a42525625cdfee60b3f4c37a25af..d5f27f042d76bbde3ab66fee25327428decd39c1 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -10,6 +10,7 @@
 #include "MCMultiCore/ModelCheckerCPPThread.h"
 #include "MCMultiCore/ModelCheckerTh.h"
 #include "MCMultiCore/ModelCheckThReq.h"
+#include "MCMultiCore/MCCPPThPor.h"
 #include "threadSOG.h"
 #include "HybridSOG.h"
 #include "Hybrid/MCHybrid/MCHybridSOG.h"
@@ -120,14 +121,16 @@ int main(int argc, char **argv) {
 
 
     if (n_tasks == 1) {
-        if (n_tasks == 1 && (!strcmp(argv[1], "otfPR") || !strcmp(argv[1], "otfC") || !strcmp(argv[1], "otfP"))) {
+        if (n_tasks == 1 && (!strcmp(argv[1], "otfPR") || !strcmp(argv[1], "otfC") || !strcmp(argv[1], "otfP") || !strcmp(argv[1], "otfPOR"))) {
             cout << "Performing on the fly Model checking..." << endl;
             if (!strcmp(argv[1], "otfP"))
                 cout << "Multi-threaded algorithm based on Pthread library!" << endl;
             else if (!strcmp(argv[1], "otfPR"))
                 cout << "Multi-threaded algorithm (progressive) based on PThread!" << endl;
-            else
+            else if (!strcmp(argv[1], "otfC"))
                 cout << "Multi-threaded algorithm based on C++ Thread library!" << endl;
+            else
+                cout<<"Multi-threaded algorithm (progressive) with POR!"<<endl;
             cout << "Building automata for not(formula)\n";
             auto d = spot::make_bdd_dict();
             spot::translator obj=spot::translator(d);
@@ -140,8 +143,9 @@ int main(int argc, char **argv) {
                 mcl = new ModelCheckerTh(Rnewnet, nb_th);
             else if (!strcmp(argv[1], "otfC"))
                 mcl = new ModelCheckerCPPThread(Rnewnet, nb_th);
-            else
+            else if (!strcmp(argv[1], "otfPR"))
                 mcl=new ModelCheckThReq(Rnewnet, nb_th);
+            else mcl=new MCCPPThPor(Rnewnet, nb_th);
             mcl->loadNet();
             auto k = std::make_shared<SogKripkeTh>(d, mcl, Rnewnet.getListTransitionAP(), Rnewnet.getListPlaceAP());
             cout << "Performing on the fly Modelchecking" << endl;
@@ -324,6 +328,5 @@ int main(int argc, char **argv) {
         }
     }
     MPI_Finalize();
-
 	return (EXIT_SUCCESS);
 }