Skip to content
Snippets Groups Projects
Commit f9c2bf6c authored by Jaime Arias's avatar Jaime Arias
Browse files

wip: expression

parent e351143b
No related branches found
No related tags found
No related merge requests found
Pipeline #9937 failed with stage
......@@ -37,6 +37,15 @@
return weight[PosTransInWeight(in)][PosTransOutWeight(out)];
}*/
int Aggregate::id() const{
return id_;
}
void Aggregate::set_id(const int id){
id_= id;
}
Aggregate* Aggregate::GetsuccessorsOfTrans(int t) const
{
for (const Edge p : successors) {
......
......@@ -16,7 +16,10 @@ struct Edge {
typedef std::vector<Edge> Edges;
class Aggregate {
public:
private:
int id_;
public:
/**
* Constructor
*/
......@@ -31,6 +34,14 @@ class Aggregate {
* BDD of the aggregate
*/
bdd bdd_state;
/*
* Get the id of the aggregate
*/
int id() const;
/*
* Set the id of the aggregate
*/
void set_id(int id);
/*
* Input transitions of the aggregate
*/
......
......@@ -409,12 +409,15 @@ int PetriNetSOG::ComputeSingleMaxWeight(const Aggregate *aggr, const int in,
void PetriNetSOG::GenerateSOG(SOG &sog) const {
Stack st;
int aggr_cpt = 0;
// construction of the first aggregate
auto *new_aggregate = new Aggregate;
const bdd complete_aggr = AccessibleEpsilon(m0);
new_aggregate->bdd_state = complete_aggr;
new_aggregate->set_id(aggr_cpt);
aggr_cpt++;
sog.set_initial_state(new_aggregate);
sog.AddState(new_aggregate);
......@@ -445,6 +448,8 @@ void PetriNetSOG::GenerateSOG(SOG &sog) const {
// if aggregate does not exist in the sog
if (!pos) {
succ_aggr->set_id(aggr_cpt);
aggr_cpt++;
sog.AddState(succ_aggr);
sog.AddArc(curr_aggr.aggregate, succ_aggr, t);
......@@ -477,6 +482,7 @@ Paths PetriNetSOG::ObservablePaths(SOG &sog, map<int, int> trans_obs) const {
Set covered_trans;
Set firable_trans;
Stack st;
int aggr_cpt = 0;
// construction of the first aggregate
auto *c = new Aggregate;
......@@ -487,7 +493,8 @@ Paths PetriNetSOG::ObservablePaths(SOG &sog, map<int, int> trans_obs) const {
firable_trans = FirableObservableTrans(complete_aggr);
st.emplace(c, firable_trans);
}
c->set_id(aggr_cpt);
aggr_cpt++;
sog.set_initial_state(c);
sog.AddState(c);
......@@ -539,6 +546,8 @@ Paths PetriNetSOG::ObservablePaths(SOG &sog, map<int, int> trans_obs) const {
firable_trans = FirableObservableTrans(complete_aggr);
// add the aggregate and its predecessors to the graph
reached_aggr->set_id(aggr_cpt);
aggr_cpt++;
sog.AddState(reached_aggr);
sog.AddArc(elt.aggregate, reached_aggr, t);
......@@ -651,3 +660,112 @@ Path PetriNetSOG::SubPathAggregate(bdd *source, const bdd &target,
*source = current_state;
return path;
}
void ConcatSequences(const std::string &seq, const Lg &lg, Lg &updated_lg) {
for (const LgElement &e : lg) {
updated_lg.push_back({seq + e.first, e.second});
}
}
std::string JoinSequencesOfLg(const Lg &lg) {
std::string seq;
for (const LgElement &f : lg) {
seq += "(" + f.first + ")*";
}
return "(" + seq + ")*";
}
void UpdateLanguage(const Aggregate *s, const int s0, std::map<int, Lg> &lg_map,
std::set<int> &visited) {
if (visited.find(s->id()) != visited.end()) {
Lg updated_lg = {};
for (const LgElement &e : lg_map[s->id()]) {
const std::string seq_e = e.first;
const Aggregate *state_e = e.second;
if (state_e != nullptr && state_e->id() != s0) {
UpdateLanguage(state_e, s0, lg_map, visited);
ConcatSequences(seq_e, lg_map[state_e->id()], updated_lg);
} else {
updated_lg.push_back(e);
}
}
lg_map[s->id()] = updated_lg;
}
}
Lg RegularExpressionGeneration(std::vector<Aggregate *> &st,
std::map<int, Lg> &lg_map,
std::set<int> &visited, const int s0) {
Aggregate *cur = nullptr;
if (!st.empty()) {
cur = st.back();
// check if current Aggregate has no successors
if (cur->successors.empty()) {
lg_map[cur->id()] = {{"", nullptr}};
} else {
lg_map[cur->id()] = {};
}
// Process each successor of the current state
for (const Edge &succ : cur->successors) {
std::string label = std::to_string(succ.transition);
Aggregate *next = succ.state;
if (find(st.begin(), st.end(), next) != st.end()) {
lg_map[cur->id()].push_back({label, next});
} else {
if (visited.find(next->id()) != visited.end()) {
UpdateLanguage(next, s0, lg_map, visited);
} else {
st.push_back(next);
RegularExpressionGeneration(st, lg_map, visited, s0);
} // end if next is visited
// update language
ConcatSequences(label, lg_map[next->id()], lg_map[cur->id()]);
} // end if next is in the stack
} // end for over successors
// build cy and cy_compl sets
Lg cy = {};
Lg cy_compl = {};
for (const LgElement &e : lg_map[cur->id()]) {
if (e.second == cur) {
cy.push_back(e);
} else {
cy_compl.push_back(e);
}
}
if (!cy.empty()) {
std::string seq = JoinSequencesOfLg(cy);
if (!cy_compl.empty()) {
Lg updated_lg = {};
for (const LgElement &e : cy_compl) {
updated_lg.push_back({seq + e.first, e.second});
}
lg_map[cur->id()] = updated_lg;
} else {
lg_map[cur->id()] = {{seq, nullptr}};
}
}
}
cur = st.back();
st.pop_back();
visited.insert(cur->id());
return lg_map[cur->id()];
}
Lg PetriNetSOG::GenerateRegExp(const SOG *sog) const {
std::vector<Aggregate *> st;
std::map<int, Lg> lg_map;
std::set<int> visited;
// Initialize the stack with the initial aggregate
st.push_back(sog->initial_state);
return (RegularExpressionGeneration(st, lg_map, visited,
sog->initial_state->id()));
}
......@@ -48,6 +48,9 @@ class Trans {
bdd prerel;
};
typedef std::pair<std::string, Aggregate*> LgElement;
typedef std::vector<LgElement> Lg;
class PetriNetSOG {
private:
// number of places of the petri net model
......@@ -217,6 +220,11 @@ class PetriNetSOG {
* @return abstract path
*/
Path AbstractPath(Path path, const SOG& sog) const;
/**
*
*
*/
Lg GenerateRegExp(const SOG* sog) const;
};
#endif // PETRI_NET_SOG_H_
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