diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 26f1d64e8f247f28c2f49bd22dcf439eaacd1617..75f543caf8688ac67a8a55cdc045f40a1066ef3e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -75,6 +75,7 @@ add_executable(mc-sog main.cpp
         SylvanCacheWrapper.cpp SylvanCacheWrapper.h
         MCMultiCore/ModelCheckerCPPThread.cpp MCMultiCore/ModelCheckerCPPThread.h
         MCMultiCore/ModelCheckerTh.cpp MCMultiCore/ModelCheckerTh.h
+        MCMultiCore/MCThReqPor.cpp MCMultiCore/MCThReqPor.h
         threadSOG.cpp threadSOG.h
         HybridSOG.cpp HybridSOG.h
         Hybrid/MCHybrid/MCHybridSOG.cpp Hybrid/MCHybrid/MCHybridSOG.h
diff --git a/src/CommonSOG.cpp b/src/CommonSOG.cpp
index 8fc570effdf183765ba814ba2962194f1c9c4fd6..d3e397eeee434c5c082c97023fade5805eee958f 100644
--- a/src/CommonSOG.cpp
+++ b/src/CommonSOG.cpp
@@ -35,7 +35,7 @@ Set CommonSOG::firable_obs(MDD State) {
     return res;
 }
 
-MDD CommonSOG::get_successor(MDD From, int t) {
+MDD CommonSOG::get_successor(const MDD& From, const int& t) {
     return SylvanWrapper::lddmc_firing_mono(From, m_tb_relation[(t)].getMinus(), m_tb_relation[(t)].getPlus());
 }
 
@@ -123,18 +123,15 @@ MDD CommonSOG::Canonize(MDD s, unsigned int level) {
 
 /**** Detect divergence in an agregate ****/
 bool CommonSOG::Set_Div(MDD &M) const {
-
     if (m_nonObservable.empty()) {
         return false;
     }
-    Set::const_iterator i;
-    MDD Reached, From;
-
-    From = M;
+    MDD Reached, From {M};
     do {
         Reached = lddmc_false;
-        for (i = m_nonObservable.begin(); !(i == m_nonObservable.end()); i++) {
-            MDD To = SylvanWrapper::lddmc_firing_mono(From, m_tb_relation[(*i)].getMinus(), m_tb_relation[(*i)].getPlus());
+        for (auto  i : m_nonObservable )
+        {
+            MDD To = SylvanWrapper::lddmc_firing_mono(From, m_tb_relation[(i)].getMinus(), m_tb_relation[(i)].getPlus());
             Reached = SylvanWrapper::lddmc_union_mono(Reached, To);
         }
 
@@ -151,9 +148,7 @@ bool CommonSOG::Set_Bloc(MDD &M) const {
 
     MDD cur = lddmc_true;
     for (auto i : m_tb_relation) {
-
         cur = cur & (i.getMinus());
-
     }
     return ((M & cur) != lddmc_false);
     //BLOCAGE
@@ -252,5 +247,28 @@ void CommonSOG::loadNetFromFile() {
     }
     delete[] prec;
     delete[] postc;
+}
+
+void CommonSOG::AddConflict(const MDD &S, const int &transition,Set &ample) {
+   // if ()
+   MDD img= get_successor(S,transition);
+   if (img!=lddmc_true && img!=lddmc_false) {
+        for (auto i=0; i<m_transitions.size();i++) {
+            if (i!=transition) {
+                auto interPre = [this](const int & t1,const int &t2)-> bool {
+                    auto & preT1=m_transitions[t1].pre;
+                    auto & preT2=m_transitions[t2].pre;
+                    bool found=false;
+                    for (auto elt : preT1);
+                    return true;
+                };
+            }
+        }
+   }
+
+
+
+}
+bool CommonSOG::isFirable(const int &transition) {
 
 }
\ No newline at end of file
diff --git a/src/CommonSOG.h b/src/CommonSOG.h
index da68e0bca4175c46ab6abb45f3ec3a9983cee92e..5118d65c98009d383aa1e64983d24509a0013cd1 100644
--- a/src/CommonSOG.h
+++ b/src/CommonSOG.h
@@ -50,7 +50,7 @@ class CommonSOG
         vector<class Transition> m_transitions;
         MDD Accessible_epsilon(MDD From);
         Set firable_obs(MDD State);
-        MDD get_successor(MDD From, int t);
+        MDD get_successor(const MDD& From,const int& t);
         MDD ImageForward(MDD From);
         MDD Canonize(MDD s, unsigned int level);
         bool Set_Div(MDD &M) const;
@@ -59,8 +59,10 @@ class CommonSOG
         std::mutex m_graph_mutex,m_gc_mutex;  
         atomic<uint8_t> m_gc;
         volatile bool m_finish=false;
+        // Functions for POR
+        void AddConflict(const MDD& S,const int &transition,Set& ample);
     private:
-
+        bool isFirable(const int &transition);
 };
 
 #endif // COMMONSOG_H
diff --git a/src/Hybrid/MCHybrid/MCHybridSOG.cpp b/src/Hybrid/MCHybrid/MCHybridSOG.cpp
index dd5980c880e47078723d403fc9c0925f77b1d1ec..121d3645b27362345f27ab67ced29f5cf1e09622 100644
--- a/src/Hybrid/MCHybrid/MCHybridSOG.cpp
+++ b/src/Hybrid/MCHybrid/MCHybridSOG.cpp
@@ -112,7 +112,7 @@ void *MCHybridSOG::doCompute() {
             /******************************* Construction des aggregats ************************************/
 
         else {
-            while (m_Terminated == false) {
+            while (!m_Terminated) {
             std::unique_lock<std::mutex> lk(m_mutexCond);
             m_condStack.wait(lk, [this] { return !m_common_stack.empty() || !m_received_msg.empty() || m_Terminated; });
             lk.unlock();
diff --git a/src/Hybrid/MCHybridReq/MCHybridSOGReq.cpp b/src/Hybrid/MCHybridReq/MCHybridSOGReq.cpp
index 5ef9a912762f00d710c2dfe7420e2e0721f30a6e..7bbd91e84fc736288487fbef7334b8ba8e3e2229 100644
--- a/src/Hybrid/MCHybridReq/MCHybridSOGReq.cpp
+++ b/src/Hybrid/MCHybridReq/MCHybridSOGReq.cpp
@@ -22,8 +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;
@@ -425,8 +424,8 @@ void MCHybridSOGReq::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++) {
-        memcpy(mess_to_send + indice, &(*it), 2);
+    for (auto it : marked_places) {
+        memcpy(mess_to_send + indice, &(it), 2);
         indice += 2;
     }
     memcpy(mess_to_send + indice, &s_up, 2);
diff --git a/src/MCMultiCore/MCThReqPor.cpp b/src/MCMultiCore/MCThReqPor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..719c200edbdfa2d49c96f34e32240d693377531b
--- /dev/null
+++ b/src/MCMultiCore/MCThReqPor.cpp
@@ -0,0 +1,159 @@
+#include "MCThReqPor.h"
+#include <unistd.h>
+#include <thread>
+
+#define LEVEL 3
+
+MCThReqPor::MCThReqPor(const NewNet &R, int nbThread) : ModelCheckBaseMT(R, nbThread) {
+}
+
+
+void MCThReqPor::preConfigure() {
+    //cout<<"Enter : "<<__func__ <<endl;
+    initializeLDD();
+    loadNetFromFile();
+}
+
+/**
+ * Creates builder threads
+ */
+void MCThReqPor::ComputeTh_Succ() {
+
+    m_id_thread = 0;
+    //cout<<"Enter : "<<__func__ <<endl;
+    pthread_barrier_init(&m_barrier_threads, NULL, m_nb_thread + 1);
+    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;
+        }
+    }
+
+}
+
+/*
+ * Build initial aggregate
+ */
+LDDState *MCThReqPor::getInitialMetaState() {
+
+    if (m_graph->getInitialAggregate() != nullptr) {
+        return m_graph->getInitialAggregate();
+    }
+    ComputeTh_Succ();
+    LDDState *c = new LDDState;
+    MDD initial_meta_state = Accessible_epsilon(m_initialMarking);
+    SylvanWrapper::lddmc_refs_push(initial_meta_state);
+    c->m_lddstate = initial_meta_state;
+    m_graph->setInitialState(c);
+    m_graph->insert(c);
+    c->setVisited();
+    Set fire = firable_obs(initial_meta_state);
+    c->m_nbSuccessorsToBeProcessed = fire.size();
+    c->setMCurrentLevel(LEVEL);
+
+    c->setDiv(Set_Div(initial_meta_state));
+    c->setDeadLock(Set_Bloc(initial_meta_state));
+    if (!fire.empty()) {
+
+        for (auto it = fire.begin(); it != fire.end(); it++)
+            m_common_stack.push(couple_th(c, *it));
+        std::unique_lock<std::mutex> lk(m_mutexBuildCompleted);
+        m_datacondBuildCompleted.wait(lk, [c] { return c->isCompletedSucc(); });
+        lk.unlock();
+    } else c->setCompletedSucc();
+    return c;
+}
+
+/*
+ * Build successors of @agregate
+ */
+void MCThReqPor::buildSucc(LDDState *agregate) {
+    if (!agregate->isVisited()) {
+        agregate->setVisited();
+        if (agregate->getMCurrentLevel() == 0) {
+            Set fire = firable_obs(agregate->m_lddstate);
+            agregate->setMCurrentLevel(LEVEL);
+            agregate->m_nbSuccessorsToBeProcessed = fire.size();
+            if (!fire.empty()) {
+                agregate->m_nbSuccessorsToBeProcessed = fire.size();
+                for (auto it = fire.begin(); it != fire.end(); it++)
+                    m_common_stack.push(couple_th(agregate, *it));
+                std::unique_lock<std::mutex> lk(m_mutexBuildCompleted);
+                m_datacondBuildCompleted.wait(lk, [agregate] { return agregate->isCompletedSucc(); });
+                lk.unlock();
+
+            } else agregate->setCompletedSucc();
+        } else {
+            std::unique_lock<std::mutex> lk(m_mutexBuildCompleted);
+            m_datacondBuildCompleted.wait(lk, [agregate] { return agregate->isCompletedSucc(); });
+            lk.unlock();
+        }
+    }
+}
+
+
+void *MCThReqPor::threadHandler(void *context) {
+    return ((MCThReqPor *) context)->Compute_successors();
+}
+
+
+void *MCThReqPor::Compute_successors() {
+    couple_th elt;
+    LDDState *pos, *aggregate;
+    do {
+        while (!m_finish && m_common_stack.try_pop(elt)) {
+            aggregate = elt.first;
+            int transition = elt.second;
+            MDD meta_state = aggregate->m_lddstate;
+            MDD complete_state = Accessible_epsilon(get_successor(meta_state, transition));
+            bool res;
+            pos = m_graph->insertFindByMDD(complete_state, res);
+            {
+                std::unique_lock guard(m_graph_mutex);
+                aggregate->Successors.insert(aggregate->Successors.begin(), LDDEdge(pos, transition));
+                pos->Predecessors.insert(pos->Predecessors.begin(),
+                                         LDDEdge(aggregate, transition));
+            }
+            if (!res) {
+                pos->setDiv(Set_Div(complete_state));
+                pos->setDeadLock(Set_Bloc(complete_state));
+            }
+            aggregate->decNbSuccessors();
+            if (aggregate->m_nbSuccessorsToBeProcessed == 0) {
+                aggregate->setCompletedSucc();
+                m_datacondBuildCompleted.notify_one();
+            }
+
+            if (aggregate->getMCurrentLevel() > 0 && pos->getMCurrentLevel() == 0) {
+                pos->setMCurrentLevel(aggregate->getMCurrentLevel() - 1);
+                if (aggregate->getMCurrentLevel() > 1) {
+                    Set fire = firable_obs(pos->getLDDValue());
+                    pos->m_nbSuccessorsToBeProcessed = fire.size();
+                    if (!fire.empty()) {
+                        for (auto it = fire.begin(); it != fire.end(); it++)
+                            m_common_stack.push(couple_th(pos, *it));
+                    } else {
+                        pos->setCompletedSucc();
+                        m_datacondBuildCompleted.notify_one();
+                    }
+
+                }
+
+            }
+            m_graph->addArc();
+
+        }
+    } while (!m_finish);
+
+
+}
+
+
+MCThReqPor::~MCThReqPor() {
+    //pthread_barrier_wait(&m_barrier_threads);
+    for (int i = 0; i < m_nb_thread; i++) {
+        m_list_thread[i]->join();
+        delete m_list_thread[i];
+    }
+}
+
diff --git a/src/MCMultiCore/MCThReqPor.h b/src/MCMultiCore/MCThReqPor.h
new file mode 100644
index 0000000000000000000000000000000000000000..8b4c345956bac779ddc089a44919caebd77cff75
--- /dev/null
+++ b/src/MCMultiCore/MCThReqPor.h
@@ -0,0 +1,30 @@
+#ifndef MCTHREQPOR_H
+#define MCTHREQPOR_H
+#include "ModelCheckBaseMT.h"
+#include <atomic>
+#include <mutex>
+#include <thread>
+#include "misc/SafeDequeue.h"
+
+typedef pair<LDDState *, int> couple_th;
+//typedef stack<pair<LDDState *,int>> pile_t;
+class MCThReqPor : public ModelCheckBaseMT {
+public:
+    MCThReqPor(const NewNet &R,int nbThread);
+    ~MCThReqPor() override;
+    void buildSucc(LDDState *agregate)  override;
+    static void *threadHandler(void *context);
+    void *Compute_successors();
+    void ComputeTh_Succ();
+    LDDState * getInitialMetaState() override;
+private:
+    void preConfigure() override;
+    SafeDequeue<couple_th> m_common_stack;
+    atomic<uint8_t> m_id_thread;
+    thread* m_list_thread[128];
+    mutable std::mutex m_mutexBuildCompleted;
+    std::condition_variable m_datacondBuildCompleted;
+    pthread_barrier_t m_barrier_threads;
+};
+#endif
+
diff --git a/src/MCMultiCore/ModelCheckerCPPThread.cpp b/src/MCMultiCore/ModelCheckerCPPThread.cpp
index bb0dfae40e3c431ae4f11f16822263b8b7083006..82dc224cc72d6d3f8f6792821c8ef8ed39bb9085 100644
--- a/src/MCMultiCore/ModelCheckerCPPThread.cpp
+++ b/src/MCMultiCore/ModelCheckerCPPThread.cpp
@@ -96,6 +96,7 @@ void ModelCheckerCPPThread::threadHandler(void *context) {
 void ModelCheckerCPPThread::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++) {