Region *
find_sm_region(TRel &tr,const SS &sr, const SS &partition, const SS &state_space,int kmax, list<Region *> &locregs, list<Region *> &minregs)
{
//	assert(er.Intersect(partition).is_empty());


    if (not sr.Intersect(partition).is_empty()) return NULL;

    //check whether a precomputed region exists in the component
    list<Region *>::const_iterator it;
    for(it=locregs.begin(); it !=locregs.end(); ++it)
    {
        Region *r = *it;
        if (r->sup() >= sr and partition.Intersect(r->sup()).is_empty()) return NULL;
    }

    //check whether a precomputed region can be used
    for(it=minregs.begin(); it !=minregs.end(); ++it)
    {
        Region *r = *it;
        if (r->sup() >= sr and partition.Intersect(r->sup()).is_empty()) return r;
    }

    queue<Region *> P;
    P.push(new Region(sr));
    Region *result = NULL;
    hash_map<Region*, bool, hashRegion, KeysReg> cache_generate_local;
    while(not P.empty())
    {
        Region *r = P.front();
        P.pop();

        string violating_event = r->choose_event_non_constant_gradient(tr);
        if (violating_event  != "")
        {

            int gmin, gmax;
            r->corner_gradients(violating_event,tr,gmin,gmax);
            int g = int(floor(double(gmin + gmax) / 2.0));

            Region *r1 = new Region(*r);
            //cout << "--  Extending arcs leaving for " << violating_event << " with g= " << g << endl;
            bool b = r1->extend_arcs_leaving(violating_event,g,kmax,tr);
            if (not b) delete r1;
            else
            {
                if (b and  (cache_generate_local.find(r1) == cache_generate_local.end()) and partition.Intersect(r1->sup()).is_empty()
                        and not(r1->proper(state_space)))
                {
                    cache_generate_local[r1] = true;
                    if (r1->is_region(tr,false))
                    {
                        minregs.push_back(r1);
                        result = r1;//cout << "   1.regio\n";r1->print();
                        break;

                        /*					 minregs.push_back(r1);
                        					 update_topset_information(tr,tr_map,r1,tmp,"");
                        					 cache_regions[r1] = r1;
                        */
                        //updating the information on the ec events;
                        /*					 map<string,bool>::iterator ite;
                        	  			 for(ite = events_ec.begin(); ite != events_ec.end(); ++ite) {
                        	  			   SS erev = tr_map[ite->first]->get_er();
                        	  				 if ((not ite->second) and rsup >= erev)  {
                        	  					 ite->second = is_excitation_closed_event(minregs, ite->first,erev,tr, states_out_er[ite->first]);
                        	  				 }
                        	  			 }
                        */
                    }
                    else
                    {
                        P.push(r1);
                    }
                }
                else delete r1;
            }

            Region *r2 = new Region(*r);
            //cout << "--  Extending arcs entering for " << violating_event << " with g= " << g +1 << endl;
            b = r2->extend_arcs_entering(violating_event,g+1,kmax,tr);
            if (not b) delete r2;
            else
            {
                if (b and (cache_generate_local.find(r2) == cache_generate_local.end()) and partition.Intersect(r2->sup()).is_empty()
                        and not(r2->proper(state_space)))
                {
                    cache_generate_local[r2] = true;
                    if (r2->is_region(tr,false))
                    {
                        minregs.push_back(r2);
                        result = r2; //cout << "   2.regio\n";r2->print();
                        break;

                        /*						minregs.push_back(r2);
                        						update_topset_information(tr,tr_map,r2,tmp,"");
                        						cache_regions[r2] = r2;
                        */
                        //updating the information on the ec events;
                        /*					  map<string,bool>::iterator ite;
                        	  				for(ite = events_ec.begin(); ite != events_ec.end(); ++ite) {
                        	  					SS erev = tr_map[ite->first]->get_er();
                        	  					if ((not ite->second) and rsup >= erev)  {
                        	  						ite->second = is_excitation_closed_event(minregs, ite->first,erev,tr, states_out_er[ite->first]);
                        	  					}
                        	  				}
                        */
                    }
                    else
                    {
                        P.push(r2);
                    }
                }
                else delete r2;
            }
        }
        else
        {
            //cout << "			3.regio\n";r->print();
            minregs.push_back(r);
            result = r;
            break;

            /*				minregs.push_back(r);
            				update_topset_information(tr,tr_map,r,tmp,"");
            				cache_regions[r] = r;*/

            //updating the information on the ec events;
            /*			  map<string,bool>::iterator ite;
            	  		for(ite = events_ec.begin(); ite != events_ec.end(); ++ite) {
            	  			SS erev = tr_map[ite->first]->get_er();
            	  			if ((not ite->second) and rsup >= erev)  {
            	  				ite->second = is_excitation_closed_event(minregs, ite->first,erev,tr, states_out_er[ite->first]);
            	  			}
            	  		}
            	  						*/
        }
    }

    while (not P.empty())
    {
        Region *r = P.front();
        P.pop();
        delete r;
    }

    return result;
}
Region *
find_cc_newregion(string /*event*/,TRel &tr,const SS &cover, Region &partition, const SS &state_space,int kmax,
                  list<Region *> &locregs, list<Region *> &minregs,map<string,int> &/*flow_map*/)
{
//	assert(er.Intersect(partition).is_empty());
//	if (not sr.Intersect(partition).is_empty()) return NULL;
    if (not partition.test_additive_union(Region(cover),kmax)) return NULL;


    //check whether a precomputed region can be used
    list<Region *>::const_iterator it;
    for(it=minregs.begin(); it !=minregs.end(); ++it)
    {
        Region *r = *it;
        if (r->sup() >= cover and partition.test_additive_union(*r,kmax))
        {
            list<Region *>::const_iterator it;
            bool exist = false;
            for(it=locregs.begin(); it!=locregs.end() and not exist; ++it)
            {
                if ((**it) == (*r)) exist=true;
            }
            if (not exist) return r;
        }
    }


    queue<Region *> P;
    P.push(new Region(cover));
    Region *result = NULL;
    hash_map<Region*, bool, hashRegion, KeysReg> cache_generate_local;
    while(not P.empty())
    {
        Region *r = P.front();
        P.pop();

        string violating_event = r->choose_event_non_constant_gradient(tr);
        if (violating_event  != "")
        {

            int gmin, gmax;
            r->corner_gradients(violating_event,tr,gmin,gmax);
            int g = int(floor(double(gmin + gmax) / 2.0));

            Region *r1 = new Region(*r);
            //cout << "--  Extending arcs leaving for " << violating_event << " with g= " << g << endl;
            bool b = r1->extend_arcs_leaving(violating_event,g,kmax,tr);
            if (not b) delete r1;
            else
            {
                if (b and  (cache_generate_local.find(r1) == cache_generate_local.end()) and partition.test_additive_union(*r1,kmax)
                        and not(r1->proper(state_space)))
                {
                    cache_generate_local[r1] = true;
                    if (r1->is_region(tr,false))
                    {
                        bool exist = false;
                        list<Region *>::const_iterator it;
                        for(it=locregs.begin(); it!=locregs.end() and not exist; ++it)
                        {
                            if ((**it) == (*r1)) exist=true;
                        }
                        if (not exist)
                        {
                            minregs.push_back(r1);
                            result = r1;//cout << "   1.regio\n";r1->print();
                            break;
                        }
                    }
                    else
                    {
                        P.push(r1);
                    }
                }
                else delete r1;
            }

            Region *r2 = new Region(*r);
            //cout << "--  Extending arcs entering for " << violating_event << " with g= " << g +1 << endl;
            b = r2->extend_arcs_entering(violating_event,g+1,kmax,tr);
            if (not b) delete r2;
            else
            {
                if (b and (cache_generate_local.find(r2) == cache_generate_local.end()) and partition.test_additive_union(*r2,kmax)
                        and not(r2->proper(state_space)))
                {
                    cache_generate_local[r2] = true;
                    if (r2->is_region(tr,false))
                    {
                        bool exist = false;
                        list<Region *>::const_iterator it;
                        for(it=locregs.begin(); it!=locregs.end() and not exist; ++it)
                        {
                            if ((**it) == (*r2)) exist=true;
                        }
                        if (not exist)
                        {
                            minregs.push_back(r2);
                            result = r2; //cout << "   2.regio\n";r2->print();
                            break;
                        }
                    }
                    else
                    {
                        P.push(r2);
                    }
                }
                else delete r2;
            }
        }
        else
        {
//			cout << "3.regio\n";r->print();
            minregs.push_back(r);
            result = r;
            break;
        }
    }

    while (not P.empty())
    {
        Region *r = P.front();
        P.pop();
        delete r;
    }

    return result;
}