Skip to content
Snippets Groups Projects
Commit b0e6e85a authored by chihebabid's avatar chihebabid
Browse files

Fixed code for NDFS algorithm

parent 554c9765
No related branches found
No related tags found
1 merge request!6Feature/ufscc emptiness check
Pipeline #5036 passed
...@@ -44,7 +44,12 @@ void CNDFS::spawnThreads() { ...@@ -44,7 +44,12 @@ void CNDFS::spawnThreads() {
} }
void CNDFS::threadHandler(void *context) { void CNDFS::threadHandler(void *context) {
((CNDFS *) context)->dfsBlue(((CNDFS *) context)->mInitStatePtr); ((CNDFS *) context)->threadRun();
}
void CNDFS::threadRun() {
uint16_t idThread = mIdThread++;
vector<myState_t*> Rp;
dfsBlue(mInitStatePtr,Rp,idThread);
} }
//get initial state of the product automata //get initial state of the product automata
...@@ -60,23 +65,19 @@ void CNDFS::getInitialState(){ ...@@ -60,23 +65,19 @@ void CNDFS::getInitialState(){
//this function is to build a state with list of successor initially null //this function is to build a state with list of successor initially null
myState_t* CNDFS::buildState(LDDState* left, spot::state* right, bool acc, bool constructed, bool cyan){ myState_t* CNDFS::buildState(LDDState* left, spot::state* right, bool acc, bool constructed, bool cyan){
bool _cyan{false}; myState_t * buildStatePtr = new myState_t;
mMutex.lock();
myState_t * buildStatePtr = static_cast<myState_t *>(malloc(sizeof(myState_t)));
_cyan = cyan;
buildStatePtr->left = left; buildStatePtr->left = left;
buildStatePtr->right = dynamic_cast<const spot::twa_graph_state *>(right); buildStatePtr->right = dynamic_cast<const spot::twa_graph_state *>(right);
buildStatePtr->isAcceptance = acc; buildStatePtr->isAcceptance = acc;
buildStatePtr->isConstructed = constructed; buildStatePtr->isConstructed = constructed;
buildStatePtr->cyan= _cyan;
mMutex.unlock();
return buildStatePtr; return buildStatePtr;
} }
std::ostream & operator<<(std::ostream & Str,myState_t* state) { std::ostream & operator<<(std::ostream & Str,myState_t* state) {
Str << "({ Sog state= " << state->left << ", BA state= " << state->right << ", acceptance= " << state->isAcceptance << ", constructed= " << state->isConstructed << ", cyan= " << state->cyan << ", red= " << state->red << ", blue= " << state->blue << " }" << endl; Str << "({ Sog state= " << state->left << ", BA state= " << state->right << ", acceptance= " << state->isAcceptance << ", constructed= " << state->isConstructed << ", red= " << state->red << ", blue= " << state->blue << " }" << endl;
int i = 0; int i = 0;
for (auto ii : state->new_successors) for (const auto & ii : state->new_successors)
{ {
cout << "succ num " << i << ii.first << " with transition " << ii.second<< endl; cout << "succ num " << i << ii.first << " with transition " << ii.second<< endl;
i++; i++;
...@@ -84,50 +85,34 @@ std::ostream & operator<<(std::ostream & Str,myState_t* state) { ...@@ -84,50 +85,34 @@ std::ostream & operator<<(std::ostream & Str,myState_t* state) {
return Str; return Str;
} }
//all visited accepting nodes (non seed, non red) should be red
atomic_bool CNDFS::awaitCondition(myState_t* state,deque<myState_t*> localDeque)
{
vector<bool> localList ;
for (auto qu: localDeque)
{
if ((qu->isAcceptance) && (qu!=state))
localList.push_back(qu->red); // add all the red values
// return(qu->red == true);
}
//test if all elements are true
if (all_of(localList.begin(),localList.end(),[] (bool cond) {return cond ==true; }))
{
return true;
}
return false;
}
//block all threads while awaitCondition is false //block all threads while awaitCondition is false
//void CNDFS::WaitForTestCompleted(_state* state) { //void CNDFS::WaitForTestCompleted(_state* state) {
// while ( awaitCondition(state) == false) ; // while ( awaitCondition(state) == false) ;
//} //}
void CNDFS::dfsRed(myState_t* state,deque<myState_t*> localDeque) void CNDFS::dfsRed(myState_t *state, vector<myState_t*>& Rp,uint8_t idThread)
{ {
cout << "dfsRed" << endl; cout << "dfsRed" << endl;
localDeque.push_back(state); Rp.push_back(state);
computeSuccessors(state); computeSuccessors(state);
for (auto p:state->new_successors) { for (const auto& succ:state->new_successors) {
if (p.first->cyan) if (succ.first->cyan[idThread])
{ {
cout << "cycle detected" << endl; cout << "cycle detected" << endl;
exit(0); exit(0);
} }
// unvisited and not red state // unvisited and not red state
if ((find(localDeque.begin(), localDeque.end(), state) != localDeque.end()) && ! p.first->red ) if ((find(Rp.begin(), Rp.end(), state) != Rp.end()) && ! succ.first->red )
dfsRed(p.first, localDeque); dfsRed(succ.first, Rp,idThread);
} }
} }
//compute new successors of a product state //compute new successors of a product state
void CNDFS::computeSuccessors(myState_t *state) void CNDFS::computeSuccessors(myState_t *state)
{ {
LDDState* sog_current_state = state->left; auto sog_current_state = state->left;
const spot::twa_graph_state* ba_current_state = state->right; const spot::twa_graph_state* ba_current_state = state->right;
while (!sog_current_state); while (!sog_current_state);
while (!sog_current_state->isCompletedSucc()); while (!sog_current_state->isCompletedSucc());
...@@ -135,7 +120,7 @@ void CNDFS::computeSuccessors(myState_t *state) ...@@ -135,7 +120,7 @@ void CNDFS::computeSuccessors(myState_t *state)
//fetch the state's atomic proposition //fetch the state's atomic proposition
for (const auto & vv: sog_current_state->getMarkedPlaces(mMcl->getPlaceProposition())) for (const auto & vv: sog_current_state->getMarkedPlaces(mMcl->getPlaceProposition()))
{ {
string name = string(mMcl->getPlace(vv)); auto name = string(mMcl->getPlace(vv));
auto f = spot::formula::ap(name); auto f = spot::formula::ap(name);
transitionNames.push(f); transitionNames.push(f);
cv.notify_one(); cv.notify_one();
...@@ -143,7 +128,7 @@ void CNDFS::computeSuccessors(myState_t *state) ...@@ -143,7 +128,7 @@ void CNDFS::computeSuccessors(myState_t *state)
//iterate over the successors of a current aggregate //iterate over the successors of a current aggregate
for (const auto &elt : sog_current_state->Successors) for (const auto &elt : sog_current_state->Successors)
{ {
int transition = elt.second; // je récupère le numéro du transition auto transition = elt.second; // je récupère le numéro du transition
auto name = string(mMcl->getTransition(transition)); // récuprer le nom de la transition auto name = string(mMcl->getTransition(transition)); // récuprer le nom de la transition
auto f = spot::formula::ap(name);// récuperer la proposition atomique qui correspond à la transition auto f = spot::formula::ap(name);// récuperer la proposition atomique qui correspond à la transition
transitionNames.push(f); // push state'S AP to edge'S AP transitionNames.push(f); // push state'S AP to edge'S AP
...@@ -157,7 +142,7 @@ void CNDFS::computeSuccessors(myState_t *state) ...@@ -157,7 +142,7 @@ void CNDFS::computeSuccessors(myState_t *state)
while (!tempTransitionNames.empty()) while (!tempTransitionNames.empty())
{ {
//iterate over the successors of a BA state //iterate over the successors of a BA state
spot::twa_succ_iterator *ii = mAa->succ_iter(ba_current_state); auto ii = mAa->succ_iter(ba_current_state);
if (ii->first()) if (ii->first())
do { do {
if (p->var_map.find(tempTransitionNames.front()) !=p->var_map.end()) if (p->var_map.find(tempTransitionNames.front()) !=p->var_map.end())
...@@ -202,29 +187,16 @@ void CNDFS::computeSuccessors(myState_t *state) ...@@ -202,29 +187,16 @@ void CNDFS::computeSuccessors(myState_t *state)
} }
} }
int i = 1;
//Perform the dfsBlue //Perform the dfsBlue
void CNDFS::dfsBlue(myState_t *state) { void CNDFS::dfsBlue(myState_t *state, vector<myState_t*>& Rp,uint8_t idThread) {
deque<myState_t*> localDeque;
uint16_t idThread = mIdThread++; for (const auto & succ:state->new_successors)
cout<< "appel recursif " << i << endl;
i++;
state->cyan = true;
// sharedPool.push(myCouple (state->left,state->right));
mSharedPoolTemp.push(state);
cv.notify_one();
// new_successor.push(coupleSuccessor(state,2));
computeSuccessors(state);
cout << " \n current state " << state << endl;
// cout << "nbr of successors of the current state "<< state->new_successors.size() << " with thread "<< idThread<< endl;
for (auto p:state->new_successors)
{ {
// cout << "state " << p.first << endl; if (!succ.first->blue && !succ.first->cyan[idThread])
while ((!p.first->cyan) && (!p.first->blue))
{ {
transitionNames.try_pop(transitionNames.front()); dfsBlue(succ.first,Rp,idThread);
dfsBlue(p.first);
} }
} }
state->blue = true; state->blue = true;
...@@ -237,24 +209,28 @@ void CNDFS::dfsBlue(myState_t *state) { ...@@ -237,24 +209,28 @@ void CNDFS::dfsBlue(myState_t *state) {
exit(0); exit(0);
} else } else
{ {
dfsRed(state, localDeque); //looking for an accepting cycle Rp.clear();
dfsRed(state, Rp,idThread); //looking for an accepting cycle
// the thread processed the current state waits for all visited accepting nodes (non seed, non red) to turn red // the thread processed the current state waits for all visited accepting nodes (non seed, non red) to turn red
// the late red coloring forces the other acceptance states to be processed in post-order by the other threads // the late red coloring forces the other acceptance states to be processed in post-order by the other threads
std::unique_lock<std::mutex> lk(mMutex); bool cond;
while (!awaitCondition(state, localDeque)) cv.wait(lk); do {
// cv.wait(lk,[this] {return !awaitCondition(state, localDeque)}); cond = true;
lk.unlock(); for (auto iter = Rp.begin(); iter != Rp.end() && cond; ++iter) {
// notify once we have unlocked - this is important to avoid a pessimization. if ((*iter)->isAcceptance && (*iter != state)) {
awaitCondition(state,localDeque)=true; if (!(*iter)->red) cond = false;
cv.notify_all(); }
for (auto qu: localDeque) // prune other dfsRed }
} while (!cond);
for (const auto& qu: Rp) // prune other dfsRed
{ {
qu->red = true; qu->red = true;
} }
} }
cout << "no cycle detected" << endl; cout << "no cycle detected" << endl;
} }
state->cyan = false; state->cyan[idThread] = false;
} }
spot::bdd_dict_ptr *CNDFS::m_dict_ptr; spot::bdd_dict_ptr *CNDFS::m_dict_ptr;
...@@ -15,21 +15,21 @@ ...@@ -15,21 +15,21 @@
using namespace std ; using namespace std ;
typedef pair<struct myState_t*, int> coupleSuccessor; typedef pair<struct myState_t*, int> coupleSuccessor;
static constexpr uint8_t MAX_THREADS=64;
struct myState_t { struct myState_t {
LDDState *left; LDDState *left;
const spot::twa_graph_state* right; const spot::twa_graph_state* right;
vector<pair<struct myState_t*, int>> new_successors; vector<pair<struct myState_t*, int>> new_successors;
bool isAcceptance {false}; bool isAcceptance {false};
bool isConstructed {false}; bool isConstructed {false};
bool cyan {false}; array<bool,MAX_THREADS> cyan {false};
atomic<bool> blue {false}; atomic<bool> blue {false};
atomic<bool> red {false}; atomic<bool> red {false};
}; };
class CNDFS { class CNDFS {
private: private:
static constexpr uint8_t MAX_THREADS=64;
ModelCheckBaseMT * mMcl; ModelCheckBaseMT * mMcl;
spot::twa_graph_ptr mAa; spot::twa_graph_ptr mAa;
uint16_t mNbTh; uint16_t mNbTh;
...@@ -43,6 +43,7 @@ private: ...@@ -43,6 +43,7 @@ private:
static spot::bdd_dict_ptr* m_dict_ptr; static spot::bdd_dict_ptr* m_dict_ptr;
void getInitialState(); void getInitialState();
static void threadHandler(void *context); static void threadHandler(void *context);
void threadRun();
public: public:
// SafeDequeue<myCouple> sharedPool; // SafeDequeue<myCouple> sharedPool;
SafeDequeue<spot::formula> transitionNames; SafeDequeue<spot::formula> transitionNames;
...@@ -50,10 +51,10 @@ public: ...@@ -50,10 +51,10 @@ public:
CNDFS(ModelCheckBaseMT *mcl,const spot::twa_graph_ptr &af,const uint16_t& nbTh); CNDFS(ModelCheckBaseMT *mcl,const spot::twa_graph_ptr &af,const uint16_t& nbTh);
virtual ~CNDFS(); virtual ~CNDFS();
void computeSuccessors(myState_t *state); void computeSuccessors(myState_t *state);
void dfsBlue(myState_t *state); void dfsBlue(myState_t *state, vector<myState_t*>& Rp,uint8_t idThread);
void dfsRed(myState_t* state, deque<myState_t*> mydeque); void dfsRed(myState_t* state, vector<myState_t*>& Rp,uint8_t idThread);
void WaitForTestCompleted(myState_t* state); void WaitForTestCompleted(myState_t* state);
atomic_bool awaitCondition(myState_t* state,deque<myState_t*> mydeque);
myState_t* buildState(LDDState* left, spot::state* right, bool acc, bool constructed,bool cyan); myState_t* buildState(LDDState* left, spot::state* right, bool acc, bool constructed,bool cyan);
}; };
......
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