/* * Transformation LTL formulae to Buchi automata - variant 2 * - implementation * * Milan Jaros - xjaros1@fi.muni.cz */ #include #include #include #include #include "alt_graph.hh" #include "formul.hh" //#include "error/error.hh" //#include "deb/deb.hh" #ifndef DOXYGEN_PROCESSING using namespace divine; using namespace std; #endif //DOXYGEN_PROCESSING /* pomocne funkce */ bool equiv_C(const list & L1, const list & L2); void or_sum(const list >& L1, const list >& L2, list >& LV); void conjunct(const list & L1, const list & L2, list & C); void and_sum(const list >& L1, const list >& L2, list >& LV); bool equiv_ALT_gba_node_ts(ALT_gba_node_t *p_N1, ALT_gba_node_t *p_N2); void ALT_vwaa_trans_t::clear() { t_label.erase(t_label.begin(), t_label.end()); target.erase(target.begin(), target.end()); } void ALT_vwaa_trans_t::op_times(ALT_vwaa_trans_t& T1, ALT_vwaa_trans_t& T2) { LTL_label_t::iterator l_b, l_e, l_i, l2_b, l2_e, l2_i; list ::iterator t_b, t_e, t_i, t2_b, t2_e, t2_i; clear(); l2_b = T2.t_label.begin(); l2_e = T2.t_label.end(); t_label = T1.t_label; for (l2_i = l2_b; l2_i != l2_e; l2_i++) { l_b = t_label.begin(); l_e = t_label.end(); for (l_i = l_b; l_i != l_e; l_i++) { if (*l_i == *l2_i) break; } if (l_i == l_e) t_label.push_back(*l2_i); } t2_b = T2.target.begin(); t2_e = T2.target.end(); target = T1.target; for (t2_i = t2_b; t2_i != t2_e; t2_i++) { t_b = target.begin(); t_e = target.end(); for (t_i = t_b; t_i != t_e; t_i++) { if (*t_i == *t2_i) break; } if (t_i == t_e) target.push_back(*t2_i); } } bool ALT_vwaa_trans_t::operator==(const ALT_vwaa_trans_t& T) const { LTL_label_t::const_iterator l_b, l_e, l2_b, l2_e; list::const_iterator t_b, t_e, t_i, t2_b, t2_e, t2_i; if ((t_label.size() != T.t_label.size()) || (target.size() != T.target.size())) return(false); l_b = t_label.begin(); l_e = t_label.end(); l2_b = T.t_label.begin(); l2_e = T.t_label.end(); /*for (l_i = l_b; l_i != l_e; l_i++) { l2_i = find(l2_b, l2_e, *l_i); if (l2_i == l2_e) return(false); }*/ if (!LTL_equiv_labels(t_label, T.t_label)) return(false); t_b = target.begin(); t_e = target.end(); t2_b = T.target.begin(); t2_e = T.target.end(); for (t_i = t_b; t_i != t_e; t_i++) { t2_i = find(t2_b, t2_e, *t_i); if (t2_i == t2_e) return(false); } for (t2_i = t2_b; t2_i != t2_e; t2_i++) { t_i = find(t_b, t_e, *t2_i); if (t_i == t_e) return(false); } return(true); } bool ALT_vwaa_trans_t::operator!=(const ALT_vwaa_trans_t& T) const { return(!(*this == T)); } bool ALT_vwaa_node_t::is_accept() { LTL_oper_t op; if (label.get_binar_op(op)) { if (op == op_U) return(true); } return(false); } ALT_graph_t::ALT_graph_t():timer(0), simp_GBA(false) { } ALT_graph_t::ALT_graph_t(const ALT_graph_t& G):timer(G.timer), simp_GBA(G.simp_GBA) { copy_vwaa(G); copy_GBA(G); copy_BA(G); } void ALT_graph_t::copy_vwaa(const ALT_graph_t& G) { map::const_iterator gn_b, gn_e, gn_i; list ::const_iterator ad_b, ad_e, ad_i; list ::const_iterator t_b, t_e, t_i; list >::const_iterator gi_b, gi_e, gi_i; list I_S; ALT_vwaa_node_t *p_N, *p_N1; const ALT_vwaa_node_t *p_gN, *p_gN1; ALT_vwaa_trans_t Tr; gn_b = G.vwaa_node_list.begin(); gn_e = G.vwaa_node_list.end(); for (gn_i = gn_b; gn_i != gn_e; gn_i++) { p_gN = gn_i->second; p_N = add_vwaa_node(p_gN->label, p_gN->name); ad_b = p_gN->adj.begin(); ad_e = p_gN->adj.end(); for (ad_i = ad_b; ad_i != ad_e; ad_i++) { Tr.clear(); Tr.t_label = ad_i->t_label; t_b = ad_i->target.begin(); t_e = ad_i->target.end(); for (t_i = t_b; t_i != t_e; t_i++) { p_gN1 = *t_i; p_N1 = add_vwaa_node(p_gN1->label, p_gN1->name); Tr.target.push_back(p_N1); } p_N->adj.push_back(Tr); } } gi_b = G.vwaa_init_nodes.begin(); gi_e = G.vwaa_init_nodes.end(); for (gi_i = gi_b; gi_i != gi_e; gi_i++) { t_b = gi_i->begin(); t_e = gi_i->end(); I_S.erase(I_S.begin(), I_S.end()); for (t_i = t_b; t_i != t_e; t_i++) { I_S.push_back(vwaa_node_list[(*t_i)->name]); } vwaa_init_nodes.push_back(I_S); } } void ALT_graph_t::copy_GBA(const ALT_graph_t& G) { list::const_iterator gn_b, gn_e, gn_i; list::iterator gn_j; list ::const_iterator v_b, v_e, v_i; ALT_gba_node_t *p_N; ALT_vwaa_node_t *p_vN; list >::const_iterator at_b, at_e, at_i; list::const_iterator t_b, t_e, t_i; list::iterator nt_b, nt_e, nt_i; ALT_gba_trans_t *p_T = NULL; list LT; int name; gn_b = G.gba_node_list.begin(); gn_e = G.gba_node_list.end(); for (gn_i = gn_b; gn_i != gn_e; gn_i++) { p_N = new ALT_gba_node_t; p_N->name = (*gn_i)->name; gba_node_list.push_back(p_N); v_b = (*gn_i)->node_label.begin(); v_e = (*gn_i)->node_label.end(); for (v_i = v_b; v_i != v_e; v_i++) { p_vN = find_vwaa_node((*v_i)->name); if (p_vN != 0) { p_N->node_label.push_back(p_vN); } else { cerr << "Nelze najit ALT_vwaa_node_t: " << (*v_i)->name << endl; } } } gn_j = gba_node_list.begin(); for (gn_i = gn_b; gn_i != gn_e; gn_i++, gn_j++) { t_b = (*gn_i)->adj.begin(); t_e = (*gn_i)->adj.end(); for (t_i = t_b; t_i != t_e; t_i++) { p_T = new ALT_gba_trans_t; p_T->t_label = (*t_i)->t_label; p_T->p_from = *gn_j; p_T->p_to = find_gba_node((*t_i)->p_to->name); (*gn_j)->adj.push_back(p_T); } } gn_b = G.gba_init_nodes.begin(); gn_e = G.gba_init_nodes.end(); for (gn_i = gn_b; gn_i != gn_e; gn_i++) { p_N = find_gba_node((*gn_i)->name); gba_init_nodes.push_back(p_N); } at_b = G.acc_set.begin(); at_e = G.acc_set.end(); for (at_i = at_b; at_i != at_e; at_i++) { LT.erase(LT.begin(), LT.end()); t_b = at_i->begin(); t_e = at_i->end(); for (t_i = t_b; t_i != t_e; t_i++) { p_N = find_gba_node((*t_i)->p_from->name); name = (*t_i)->p_to->name; nt_b = p_N->adj.begin(); nt_e = p_N->adj.end(); for (nt_i = nt_b; nt_i != nt_e; nt_i++) { if (((*nt_i)->p_to->name == name) && LTL_equiv_labels((*nt_i)->t_label, (*t_i)->t_label)) { p_T = *nt_i; break; } } LT.push_back(p_T); } acc_set.push_back(LT); } /* list< pair >, ALT_gba_node_t*> > ALT_list_eq_gba_nodes_t */ ALT_list_eq_gba_nodes_t::const_iterator eq_b, eq_e, eq_i; list >::const_iterator lv_b, lv_e, lv_i; list LV; ALT_eq_gba_nodes_t P; eq_b = G.gba_equiv_nodes.begin(); eq_e = G.gba_equiv_nodes.end(); for (eq_i = eq_b; eq_i != eq_e; eq_i++) { P.first.erase(P.first.begin(), P.first.end()); p_N = find_gba_node(eq_i->second->name); P.second = p_N; lv_b = eq_i->first.begin(); lv_e = eq_i->first.end(); for (lv_i = lv_b; lv_i != lv_e; lv_i++) { LV.erase(LV.begin(), LV.end()); v_b = lv_i->begin(); v_e = lv_i->end(); for (v_i = v_b; v_i != v_e; v_i++) { p_vN = find_vwaa_node((*v_i)->name); LV.push_back(p_vN); } P.first.push_back(LV); } gba_equiv_nodes.push_back(P); } } void ALT_graph_t::copy_BA(const ALT_graph_t& G) { list::const_iterator n_b, n_e, n_i; list::iterator n_j; list::const_iterator t_b, t_e, t_i; ALT_ba_node_t *p_N; ALT_ba_trans_t T; n_b = G.ba_node_list.begin(); n_e = G.ba_node_list.end(); for (n_i = n_b; n_i != n_e; n_i++) { p_N = new ALT_ba_node_t; p_N->name = (*n_i)->name; p_N->citac = (*n_i)->citac; if ((*n_i)->p_old != 0) { p_N->p_old = find_gba_node((*n_i)->p_old->name); } else { p_N->p_old = 0; } ba_node_list.push_back(p_N); } n_j = ba_node_list.begin(); for (n_i = n_b; n_i != n_e; n_i++, n_j++) { t_b = (*n_i)->adj.begin(); t_e = (*n_i)->adj.end(); for (t_i = t_b; t_i != t_e; t_i++) { T.t_label = t_i->t_label; T.target = find_ba_node(t_i->target->name); (*n_j)->adj.push_back(T); } } n_b = G.ba_init_nodes.begin(); n_e = G.ba_init_nodes.end(); for (n_i = n_b; n_i != n_e; n_i++) { p_N = find_ba_node((*n_i)->name); ba_init_nodes.push_back(p_N); } n_b = G.ba_accept_nodes.begin(); n_e = G.ba_accept_nodes.end(); for (n_i = n_b; n_i != n_e; n_i++) { p_N = find_ba_node((*n_i)->name); ba_accept_nodes.push_back(p_N); } } ALT_vwaa_node_t* ALT_graph_t::find_vwaa_node(int name) { map::const_iterator n_f; n_f = vwaa_node_list.find(name); if (n_f != vwaa_node_list.end()) return(n_f->second); else return(0); } ALT_gba_node_t* ALT_graph_t::find_gba_node(int name) { list::const_iterator n_b, n_e, n_i; ALT_gba_node_t *p_N = 0; n_b = gba_node_list.begin(); n_e = gba_node_list.end(); for (n_i = n_b; n_i != n_e; n_i++) { if ((*n_i)->name == name) { p_N = *n_i; break; } } return(p_N); } ALT_ba_node_t* ALT_graph_t::find_ba_node(int name) { list::const_iterator n_b, n_e, n_i; ALT_ba_node_t *p_N = 0; n_b = ba_node_list.begin(); n_e = ba_node_list.end(); for (n_i = n_b; n_i != n_e; n_i++) { if ((*n_i)->name == name) { p_N = *n_i; break; } } return(p_N); } ALT_graph_t::~ALT_graph_t() { clear(); } ALT_graph_t& ALT_graph_t::operator=(const ALT_graph_t& G) { clear(); timer = G.timer; simp_GBA = G.simp_GBA; copy_vwaa(G); copy_GBA(G); copy_BA(G); return(*this); } void ALT_graph_t::clear() { clear_vwaa(); clear_GB(); clear_BA(); } void ALT_graph_t::clear_vwaa() { map::iterator n_b, n_e, n_i; n_b = vwaa_node_list.begin(); n_e = vwaa_node_list.end(); for (n_i = n_b; n_i != n_e; n_i++) { delete n_i->second; } vwaa_node_list.erase(n_b, n_e); vwaa_init_nodes.erase(vwaa_init_nodes.begin(), vwaa_init_nodes.end()); vwaa_accept_nodes.erase(vwaa_accept_nodes.begin(), vwaa_accept_nodes.end()); } void ALT_graph_t::clear_GB() { list::iterator gn_b, gn_e, gn_i; gn_b = gba_node_list.begin(); gn_e = gba_node_list.end(); for (gn_i = gn_b; gn_i != gn_e; gn_i++) { delete (*gn_i); } gba_node_list.erase(gn_b, gn_e); acc_set.erase(acc_set.begin(), acc_set.end()); gba_init_nodes.erase(gba_init_nodes.begin(), gba_init_nodes.end()); gba_equiv_nodes.erase(gba_equiv_nodes.begin(), gba_equiv_nodes.end()); } void ALT_graph_t::clear_BA() { list::iterator n_b, n_e, n_i; n_b = ba_node_list.begin(); n_e = ba_node_list.end(); for (n_i = n_b; n_i != n_e; n_i++) { delete (*n_i); } ba_node_list.erase(n_b, n_e); ba_init_nodes.erase(ba_init_nodes.begin(), ba_init_nodes.end()); ba_accept_nodes.erase(ba_accept_nodes.begin(), ba_accept_nodes.end()); } ALT_vwaa_node_t* ALT_graph_t::find_vwaa_node(const LTL_formul_t& F) { map::iterator n_b, n_e, n_f; n_b = vwaa_node_list.begin(); n_e = vwaa_node_list.end(); for (n_f = n_b; n_f != n_e; n_f++) { if (n_f->second->label == F) return(n_f->second); } return(0); } ALT_vwaa_node_t* ALT_graph_t::add_vwaa_node(const LTL_formul_t& F, int n) { map::iterator n_e, n_f; ALT_vwaa_node_t *p_N; n_e = vwaa_node_list.end(); n_f = vwaa_node_list.find(n); if (n_f == n_e) { p_N = new ALT_vwaa_node_t; p_N->name = n; p_N->label = F; vwaa_node_list[n] = p_N; } else { p_N = n_f->second; } return(p_N); } ALT_vwaa_node_t* ALT_graph_t::add_vwaa_node(const LTL_formul_t& F) { ALT_vwaa_node_t *p_N; p_N = find_vwaa_node(F); if (p_N == 0) { p_N = new ALT_vwaa_node_t; p_N->label = F; p_N->name = timer; vwaa_node_list[timer] = p_N; timer++; } return(p_N); } void ALT_graph_t::op_times(list& J1, list& J2, list& JV) { list::iterator j1_b, j1_e, j1_i, j2_b, j2_e, j2_i; list::iterator jv_e, jv_i; ALT_vwaa_trans_t Tr; JV.erase(JV.begin(), JV.end()); j1_b = J1.begin(); j1_e = J1.end(); j2_b = J2.begin(); j2_e = J2.end(); for (j1_i = j1_b; j1_i != j1_e; j1_i++) { for (j2_i = j2_b; j2_i != j2_e; j2_i++) { Tr.op_times(*j1_i, *j2_i); jv_e = JV.end(); jv_i = find(JV.begin(), jv_e, Tr); if (jv_i == jv_e) JV.push_back(Tr); } } } void ALT_graph_t::op_sum(list & J1, list & J2, list & JV) { list ::iterator j_b, j_e, j_i, jv_e, jv_i; JV = J1; j_b = J2.begin(); j_e = J2.end(); for (j_i = j_b; j_i != j_e; j_i++) { jv_e = JV.end(); jv_i = find(JV.begin(), jv_e, *j_i); if (jv_i == jv_e) JV.push_back(*j_i); } } bool equiv_C(const list & L1, const list & L2) { list::const_iterator l1_b, l1_e, l1_i, l2_b, l2_e, l2_i; if (L1.size() != L2.size()) return(false); l1_b = L1.begin(); l1_e = L1.end(); l2_b = L2.begin(); l2_e = L2.end(); for (l1_i = l1_b; l1_i != l1_e; l1_i++) { l2_i = find(l2_b, l2_e, *l1_i); if (l2_i == l2_e) return(false); } return(true); } void or_sum(const list >& L1, const list >& L2, list >& LV) { list >::const_iterator l_b, l_e, l_i; list >::iterator lv_e, lv_i; LV = L1; l_b = L2.begin(); l_e = L2.end(); for (l_i = l_b; l_i != l_e; l_i++) { lv_e = LV.end(); for (lv_i = LV.begin(); lv_i != lv_e; lv_i++) { if (equiv_C(*l_i, *lv_i)) break; } if (lv_i == lv_e) { LV.push_back(*l_i); } } } void conjunct(const list & L1, const list & L2, list & C) { list ::const_iterator l_b, l_e, l_i; list ::iterator c_e, c_i; C = L1; l_b = L2.begin(); l_e = L2.end(); for (l_i = l_b; l_i != l_e; l_i++) { c_e = C.end(); c_i = find(C.begin(), c_e, *l_i); if (c_i == c_e) C.push_back(*l_i); } } void and_sum(const list >& L1, const list >& L2, list >& LV) { list >::const_iterator l1_b, l1_e, l1_i; list >::const_iterator l2_b, l2_e, l2_i; list >::iterator lv_e, lv_i; list C; l1_b = L1.begin(); l1_e = L1.end(); l2_b = L2.begin(); l2_e = L2.end(); for (l1_i = l1_b; l1_i != l1_e; l1_i++) { for (l2_i = l2_b; l2_i != l2_e; l2_i++) { conjunct(*l1_i, *l2_i, C); lv_e = LV.end(); for (lv_i = LV.begin(); lv_i != lv_e; lv_i++) { if (equiv_C(*lv_i, C)) break; } if (lv_i == lv_e) LV.push_back(C); } } } void ALT_graph_t::op_over(LTL_formul_t& F, list >& LV) { map::const_iterator n_b, n_e; LTL_formul_t F1, F2; LTL_oper_t op; list C; // konjunkce stavu list > LV1, LV2; ALT_vwaa_node_t *p_N; LV.erase(LV.begin(), LV.end()); n_b = vwaa_node_list.begin(); n_e = vwaa_node_list.end(); switch (F.typ()) { case LTL_LITERAL: case LTL_BOOL: case LTL_NEXT_OP: p_N = find_vwaa_node(F); C.push_back(p_N); LV.push_back(C); return; break; case LTL_BIN_OP: F.get_binar_op(op, F1, F2); switch (op) { case op_U: case op_V: p_N = find_vwaa_node(F); C.push_back(p_N); LV.push_back(C); return; break; case op_or: op_over(F1, LV1); op_over(F2, LV2); or_sum(LV1, LV2, LV); return; break; case op_and: op_over(F1, LV1); op_over(F2, LV2); and_sum(LV1, LV2, LV); return; break; } } } void ALT_graph_t::mkDELTA(LTL_formul_t& F, list & LV) { list LT1, LT2; ALT_vwaa_node_t *p_N; LTL_formul_t F1, F2; LTL_oper_t op; switch (F.typ()) { case LTL_LITERAL: case LTL_BOOL: case LTL_NEXT_OP: p_N = find_vwaa_node(F); mkdelta(p_N, LV); break; case LTL_BIN_OP: F.get_binar_op(op); switch (op) { case op_U: case op_V: p_N = find_vwaa_node(F); mkdelta(p_N, LV); break; case op_and: F.get_binar_op(op, F1, F2); mkDELTA(F1, LT1); mkDELTA(F2, LT2); op_times(LT1, LT2, LV); break; case op_or: F.get_binar_op(op, F1, F2); mkDELTA(F1, LT1); mkDELTA(F2, LT2); op_sum(LT1, LT2, LV); break; } break; } } void ALT_graph_t::mkdelta(ALT_vwaa_node_t *p_N, list & LV) { list > LLN; list >::iterator lln_b, lln_e, lln_i; bool b; ALT_vwaa_trans_t Tr; LTL_formul_t F1, F2; LTL_oper_t op; LTL_literal_t Lit; list LT1, LT2, LT3, LT4; LV.erase(LV.begin(), LV.end()); switch (p_N->label.typ()) { case LTL_BOOL: p_N->label.get_bool(b); if (b) { LV.push_back(Tr); } break; case LTL_LITERAL: p_N->label.get_literal(Lit.negace, Lit.predikat); Tr.t_label.push_back(Lit); LV.push_back(Tr); break; case LTL_NEXT_OP: p_N->label.get_next_op(F1); op_over(F1, LLN); lln_b = LLN.begin(); lln_e = LLN.end(); for (lln_i = lln_b; lln_i != lln_e; lln_i++) { Tr.target = *lln_i; LV.push_back(Tr); } break; case LTL_BIN_OP: p_N->label.get_binar_op(op, F1, F2); switch (op) { case op_U: mkDELTA(F2, LT1); Tr.target.push_back(p_N); LT2.push_back(Tr); mkDELTA(F1, LT3); op_times(LT2, LT3, LT4); op_sum(LT1, LT4, LV); break; case op_V: mkDELTA(F1, LT1); Tr.target.push_back(p_N); LT2.push_back(Tr); op_sum(LT1, LT2, LT3); mkDELTA(F2, LT4); op_times(LT3, LT4, LV); break; default:break;//nothing } break; } } void ALT_graph_t::create_graph(LTL_formul_t& F_in) { LTL_formul_t F1, F2, F; LTL_oper_t op; queue QF; clear(); timer = 1; QF.push(F_in); while (!QF.empty()) { F = QF.front(); QF.pop(); switch (F.typ()) { case LTL_BOOL: case LTL_LITERAL: //cerr << "add " << F << endl; add_vwaa_node(F); break; case LTL_NEXT_OP: //cerr << "add " << F << endl; add_vwaa_node(F); F.get_next_op(F1); QF.push(F1); break; case LTL_BIN_OP: F.get_binar_op(op, F1, F2); QF.push(F1); QF.push(F2); if ((op == op_U) || (op == op_V)) { //cerr << "add " << F << endl; add_vwaa_node(F); } break; } } /* cast druha - doplneni prechodove funkce */ map::iterator nl_b, nl_e, nl_i; ALT_vwaa_node_t *p_N; op_over(F_in, vwaa_init_nodes); nl_b = vwaa_node_list.begin(); nl_e = vwaa_node_list.end(); for (nl_i = nl_b; nl_i != nl_e; nl_i++) { p_N = nl_i->second; mkdelta(p_N, p_N->adj); list ::iterator tr_i, tr_j; tr_i = p_N->adj.begin(); while (tr_i != p_N->adj.end()) { if (LTL_is_contradiction(tr_i->t_label)) { tr_j = tr_i; tr_i++; p_N->adj.erase(tr_j); } else { tr_i++; } } } /* cast treti - zjednoduseni automatu */ map pom_node_list; list >::iterator in_i, in_e; list ::iterator l_e, l_i; list ::iterator ad_e, ad_i; queue QN; for (nl_i = nl_b; nl_i != nl_e; nl_i++) { nl_i->second->pom = false; } in_e = vwaa_init_nodes.end(); for (in_i = vwaa_init_nodes.begin(); in_i != in_e; in_i++) { l_e = in_i->end(); for (l_i = in_i->begin(); l_i != l_e; l_i++) { if (!(*l_i)->pom) { QN.push(*l_i); (*l_i)->pom = true; } } } while (!QN.empty()) { p_N = QN.front(); QN.pop(); ad_e = p_N->adj.end(); for (ad_i = p_N->adj.begin(); ad_i != ad_e; ad_i++) { l_e = ad_i->target.end(); for (l_i = ad_i->target.begin(); l_i != l_e; l_i++) { if (!(*l_i)->pom) { QN.push(*l_i); (*l_i)->pom = true; } } } } for (nl_i = nl_b; nl_i != nl_e; nl_i++) { if (nl_i->second->pom) { pom_node_list[nl_i->first] = nl_i->second; } else { delete nl_i->second; } } vwaa_node_list = pom_node_list; /* doplneni akceptujicich stavu */ nl_b = vwaa_node_list.begin(); nl_e = vwaa_node_list.end(); for (nl_i = nl_b; nl_i != nl_e; nl_i++) { if (nl_i->second->is_accept()) vwaa_accept_nodes.push_back(nl_i->second); } } void ALT_graph_t::vypis_vwaa() { list >::const_iterator in_b, in_e, in_i; list ::const_iterator n_b, n_e, n_i; map::const_iterator nl_b, nl_e, nl_i; list ::const_iterator t_b, t_e, t_i; LTL_label_t::const_iterator f_b, f_e, f_i; bool b, b1; const ALT_vwaa_node_t *p_N; int node_counter = 0, trans_counter = 0, acc_counter = 0; cout << endl; cout << "Initial: {"; in_b = vwaa_init_nodes.begin(); in_e = vwaa_init_nodes.end(); b = false; for (in_i = in_b; in_i != in_e; in_i++) { if (b) { cout << ", "; } else { b = true; } cout << "{"; n_b = in_i->begin(); n_e = in_i->end(); b1 = false; for (n_i = n_b; n_i != n_e; n_i++) { if (b1) { cout << ", "; } else { b1 = true; } cout << (*n_i)->name; } cout << "}"; } cout << "}" << endl; //cerr << ALT_vwaa_node_t_list.size(); nl_b = vwaa_node_list.begin(); nl_e = vwaa_node_list.end(); for (nl_i = nl_b; nl_i != nl_e; nl_i++) { node_counter++; p_N = nl_i->second; cout << p_N->name << ": " << p_N->label << " -> {"; t_b = p_N->adj.begin(); t_e = p_N->adj.end(); b = false; for (t_i = t_b; t_i != t_e; t_i++) { trans_counter++; if (b) { cout << ", "; } else { b = true; } cout << "(<"; f_b = t_i->t_label.begin(); f_e = t_i->t_label.end(); b1 = false; for (f_i = f_b; f_i != f_e; f_i++) { if (b1) { cout << ", "; } else { b1 = true; } cout << *f_i; } cout << "> ; {"; n_b = t_i->target.begin(); n_e = t_i->target.end(); b1 = false; for (n_i = n_b; n_i != n_e; n_i++) { if (b1) { cout << ", "; } else { b1 = true; } cout << (*n_i)->name; } cout << "})"; } cout << "}" << endl; } cout << "Accept: {"; b = false; for (nl_i = nl_b; nl_i != nl_e; nl_i++) { if (nl_i->second->is_accept()) { acc_counter++; if (b) { cout << ", "; } else { b = true; } cout << nl_i->second->name; } } cout << "}" << endl << endl; cout << "nodes: " << node_counter << "; transitions: " << trans_counter << "; initial: " << vwaa_init_nodes.size() << "; accept nodes: " << acc_counter << endl; } /* GBA */ ALT_gba_node_t::~ALT_gba_node_t() { list::iterator tr_e, tr_i; tr_e = adj.end(); for (tr_i = adj.begin(); tr_i != tr_e; tr_i++) { delete *tr_i; } } /* k nalezeni uzlu pouzije seznam gba_equiv_nodes */ ALT_gba_node_t* ALT_graph_t::find_gba_node(const list & node_label) { /*list< pair >, ALT_gba_node_t*> >*/ ALT_list_eq_gba_nodes_t::iterator eqn_b, eqn_e, eqn_i; list >::iterator n_b, n_e, n_i; eqn_b = gba_equiv_nodes.begin(); eqn_e = gba_equiv_nodes.end(); for (eqn_i = eqn_b; eqn_i != eqn_e; eqn_i++) { n_b = eqn_i->first.begin(); n_e = eqn_i->first.end(); for (n_i = n_b; n_i != n_e; n_i++) { if (equiv_C(*n_i, node_label)) { return(eqn_i->second); } } } return(0); } ALT_gba_node_t* ALT_graph_t::mknode(const list & LN, bool& b) { ALT_gba_node_t *p_N1; p_N1 = find_gba_node(LN); if (p_N1 == 0) { p_N1 = new ALT_gba_node_t; p_N1->node_label = LN; p_N1->name = timer; timer++; gba_node_list.push_back(p_N1); ALT_eq_gba_nodes_t eqN; eqN.first.push_back(LN); eqN.second = p_N1; gba_equiv_nodes.push_back(eqN); /*cerr << "creating node " << p_N1->name << " : "; bool b1 = false; list ::const_iterator n_b, n_e, n_i; n_b = LN.begin(); n_e = LN.end(); for (n_i = n_b; n_i != n_e; n_i++) { if (b1) { cout << ", "; } else { b1 = true; } cout << (*n_i)->label; } cout << endl;*/ b = true; return(p_N1); } else { b = false; return(p_N1); } } bool subset_eq(const list & LN1, const list & LN2) { list ::const_iterator l1_b, l1_e, l1_i, l2_b, l2_e, l2_i; if (LN1.size() > LN2.size()) return(false); l1_b = LN1.begin(); l1_e = LN1.end(); l2_b = LN2.begin(); l2_e = LN2.end(); for (l1_i = l1_b; l1_i != l1_e; l1_i++) { l2_i = find(l2_b, l2_e, *l1_i); if (l2_i == l2_e) return(false); } return(true); } bool ALT_graph_t::less_eq(ALT_vwaa_trans_t& T1, ALT_vwaa_trans_t& T2) { // T1 <= T2 list ::const_iterator ac_b, ac_e, ac_i; /* T1.target \subseteq T2.target */ if (!subset_eq(T1.target, T2.target)) return(false); //if (!equiv_C(T1.target, T2.target)) return(false); /* \Sigma(T2.t_label) \subseteq \Sigma(T1.t_label) */ /* T1.t_label \subseteq T2.t_label */ //if (!subset_eq(T2.t_label, T1.t_label)) return(false); if (!LTL_subset_label(T1.t_label, T2.t_label)) return(false); ac_b = vwaa_accept_nodes.begin(); ac_e = vwaa_accept_nodes.end(); for (ac_i = ac_b; ac_i != ac_e; ac_i++) { if (is_acc_trans(T2, *ac_i)) { if (!is_acc_trans(T1, *ac_i)) { return(false); } } } return(true); } bool ALT_graph_t::is_acc_trans(ALT_vwaa_trans_t& T, ALT_vwaa_node_t *p_ac_N) { list ::const_iterator n_b, n_e, n_i, n_f; list ::const_iterator t_b, t_e, t_i; n_b = T.target.begin(); n_e = T.target.end(); n_i = find(n_b, n_e, p_ac_N); if (n_i == n_e) return(true); t_b = p_ac_N->adj.begin(); t_e = p_ac_N->adj.end(); for (t_i = t_b; t_i != t_e; t_i++) { if (subset_eq(t_i->target, T.target)) { n_f = find(t_i->target.begin(), t_i->target.end(), p_ac_N); if (n_f == t_i->target.end()) { if (LTL_subset_label(t_i->t_label, T.t_label)) return(true); } } } return(false); } bool ALT_graph_t::is_acc_trans(ALT_gba_trans_t& T, ALT_vwaa_node_t *p_ac_N) { list ::const_iterator n_b, n_e, n_i, n_f; list ::const_iterator t_b, t_e, t_i; n_b = T.p_to->node_label.begin(); n_e = T.p_to->node_label.end(); //n_b = T.target.begin(); n_e = T.target.end(); n_i = find(n_b, n_e, p_ac_N); if (n_i == n_e) return(true); t_b = p_ac_N->adj.begin(); t_e = p_ac_N->adj.end(); for (t_i = t_b; t_i != t_e; t_i++) { if (subset_eq(t_i->target, T.p_to->node_label)) { n_f = find(t_i->target.begin(), t_i->target.end(), p_ac_N); if (n_f == t_i->target.end()) { if (LTL_subset_label(t_i->t_label, T.t_label)) return(true); } } } return(false); } void ALT_graph_t::mkdelta(ALT_gba_node_t *p_N, list& new_nodes) { list LT, LT1; list ::iterator vt_b, vt_e, vt_i, vt_i1; list ::iterator tr_b, tr_e, tr_i, tr_i1, tr_i2; list ::iterator ac_b, ac_e, ac_i; list >::iterator sas_i; ac_b = vwaa_accept_nodes.begin(); ac_e = vwaa_accept_nodes.end(); new_nodes.erase(new_nodes.begin(), new_nodes.end()); if (p_N->node_label.size() == 0) { ALT_gba_trans_t *p_Tr; p_Tr = new ALT_gba_trans_t; p_Tr->p_from = p_N; p_Tr->p_to = p_N; p_N->adj.push_back(p_Tr); if (simp_GBA) { sas_i = acc_set.begin(); for (ac_i = ac_b; ac_i != ac_e; ac_i++) { if (is_acc_trans(*p_Tr, *ac_i)) { sas_i->push_back(p_Tr); } sas_i++; } } return; } if (p_N->node_label.size() == 1) { LT = (p_N->node_label.front())->adj; } else { vt_b = p_N->node_label.begin(); vt_e = p_N->node_label.end(); vt_i = vt_b; vt_i1 = vt_b; vt_i1++; op_times((*vt_i)->adj, (*vt_i1)->adj, LT); if (p_N->node_label.size() > 2) for (vt_i1++; vt_i1 != vt_e; vt_i1++) { op_times(LT, (*vt_i1)->adj, LT1); LT = LT1; } } tr_b = LT.begin(); tr_e = LT.end(); /**/ tr_i = LT.begin(); while (tr_i != LT.end()) { if (LTL_is_contradiction(tr_i->t_label)) { tr_i2 = tr_i; tr_i++; LT.erase(tr_i2); continue; } tr_i1 = LT.begin(); while (tr_i1 != LT.end()) { if (tr_i1 == tr_i) { tr_i1++; continue; } if (less_eq(*tr_i, *tr_i1)) { tr_i2 = tr_i1; tr_i2++; LT.erase(tr_i1); tr_i1 = tr_i2; } else { tr_i1++; } } tr_i++; } /**/ /* Pri on-the-fly optimalizaci: porovnat vygenerovane prechody v LT a zjednodussit */ if (simp_GBA) { ALT_list_eq_gba_nodes_t::iterator eqn_b, eqn_e, eqn_i; list >::iterator lvn_b, lvn_e, lvn_i; bool is_new; eqn_b = gba_equiv_nodes.begin(); eqn_e = gba_equiv_nodes.end(); tr_i = LT.begin(); while (tr_i != LT.end()) { for (eqn_i = eqn_b; eqn_i != eqn_e; eqn_i++) { lvn_b = eqn_i->first.begin(); lvn_e = eqn_i->first.end(); for (lvn_i = lvn_b; lvn_i != lvn_e; lvn_i++) { if (equiv_C(*lvn_i, tr_i->target)) break; } if (lvn_i != lvn_e) break; } is_new = (eqn_i == eqn_e); tr_i1 = LT.begin(); while (tr_i1 != LT.end()) { if (tr_i == tr_i1) { tr_i1++; continue; } if (!LTL_subset_label(tr_i->t_label, tr_i1->t_label)) { tr_i1++; continue; } if (is_new) { if (!equiv_C(tr_i->target, tr_i1->target)) { tr_i1++; continue; } } else { for (lvn_i = lvn_b; lvn_i != lvn_e; lvn_i++) { if (equiv_C(tr_i1->target,*lvn_i)) break; } if (lvn_i == lvn_e) { tr_i1++; continue; } } for (ac_i = ac_b; ac_i != ac_e; ac_i++) { if (is_acc_trans(*tr_i1, *ac_i)) if (!is_acc_trans(*tr_i, *ac_i)) break; } if (ac_i == ac_e) { tr_i2 = tr_i1; tr_i1++; LT.erase(tr_i2); } else { tr_i1++; } } tr_i++; } } ALT_gba_node_t *p_N1; ALT_gba_trans_t *p_Tr; bool b; tr_b = LT.begin(); tr_e = LT.end(); for (tr_i = tr_b; tr_i != tr_e; tr_i++) { p_N1 = mknode(tr_i->target, b); if (b) { new_nodes.push_back(p_N1); } p_Tr = new ALT_gba_trans_t; p_Tr->t_label = tr_i->t_label; p_Tr->p_from = p_N; p_Tr->p_to = p_N1; p_N->adj.push_back(p_Tr); if (simp_GBA) { sas_i = acc_set.begin(); for (ac_i = ac_b; ac_i != ac_e; ac_i++) { if (is_acc_trans(*p_Tr, *ac_i)) { sas_i->push_back(p_Tr); } sas_i++; } } } } void ALT_graph_t::transform_vwaa() { map::const_iterator vwl_b, vwl_e; list >::const_iterator vwi_b, vwi_e, vwi_i; list ::iterator ac_b, ac_e, ac_i; list >::iterator sas_i; list::iterator tr_i1; queue QN; ALT_gba_node_t *p_N; bool b, b1; list new_nodes; list::iterator nn_b, nn_e, nn_i; clear_GB(); timer = 1; ac_b = vwaa_accept_nodes.begin(); ac_e = vwaa_accept_nodes.end(); if (simp_GBA) { list L; for (ac_i = ac_b; ac_i != ac_e; ac_i++) { acc_set.push_back(L); } } vwl_b = vwaa_node_list.begin(); vwl_e = vwaa_node_list.end(); vwi_b = vwaa_init_nodes.begin(); vwi_e = vwaa_init_nodes.end(); for (vwi_i = vwi_b; vwi_i != vwi_e; vwi_i++) { p_N = mknode(*vwi_i, b); if (b) { QN.push(p_N); gba_init_nodes.push_back(p_N); } } while (!QN.empty()) { p_N = QN.front(); QN.pop(); //cerr << "creating delta of " << p_N->name << endl; mkdelta(p_N, new_nodes); nn_b = new_nodes.begin(); nn_e = new_nodes.end(); for (nn_i = nn_b; nn_i != nn_e; nn_i++) { QN.push(*nn_i); } if (simp_GBA && new_nodes.empty()) { ALT_list_eq_gba_nodes_t::iterator eqn_b, eqn_e, eqn_i, eqn_i1; list::iterator tr_b, tr_e, tr_i; list::iterator gn_f; ALT_gba_node_t *p_N1; eqn_b = gba_equiv_nodes.begin(); eqn_e = gba_equiv_nodes.end(); for (eqn_i = eqn_b; eqn_i != eqn_e; eqn_i++) { if ((eqn_i->second != p_N) && equiv_ALT_gba_node_ts(p_N, eqn_i->second)) { break; } } if (eqn_i != eqn_e) { b1 = false; p_N1 = eqn_i->second; for (eqn_i1 = eqn_b; eqn_i1 != eqn_e; eqn_i1++) { if (eqn_i1->second == p_N) break; } eqn_i->first.insert(eqn_i->first.end(), eqn_i1->first.begin(), eqn_i1->first.end()); gba_equiv_nodes.erase(eqn_i1); eqn_b = gba_equiv_nodes.begin(); eqn_e = gba_equiv_nodes.end(); for (eqn_i = eqn_b; eqn_i != eqn_e; eqn_i++) { tr_b = eqn_i->second->adj.begin(); tr_e = eqn_i->second->adj.end(); b = false; for (tr_i = tr_b; tr_i != tr_e; tr_i++) { if ((*tr_i)->p_to == p_N){ (*tr_i)->p_to = p_N1; b = true; } } if (b) { simp_gba_trans(eqn_i->second); //b1 = true; } } gn_f = find(gba_node_list.begin(), gba_node_list.end(), p_N); gba_node_list.erase(gn_f); /*if (b1) { simp_ALT_gba_node_ts(); }*/ (void)b1; sas_i = acc_set.begin(); for (ac_i = ac_b; ac_i != ac_e; ac_i++) { tr_i = sas_i->begin(); while (tr_i != sas_i->end()) { if ((*tr_i)->p_from == p_N) { tr_i1 = tr_i; tr_i++; sas_i->erase(tr_i1); } else { tr_i++; } } sas_i++; } delete p_N; } } } /* doplneni akc. hran */ if (!simp_GBA) { list ::iterator va_b, va_e, va_i; list::iterator nl_b, nl_e, nl_i; list LT; list::iterator tr_b, tr_e, tr_i; va_b = vwaa_accept_nodes.begin(); va_e = vwaa_accept_nodes.end(); nl_b = gba_node_list.begin(); nl_e = gba_node_list.end(); for (va_i = va_b; va_i != va_e; va_i++) { for (nl_i = nl_b; nl_i != nl_e; nl_i++) { tr_b = (*nl_i)->adj.begin(); tr_e = (*nl_i)->adj.end(); for (tr_i = tr_b; tr_i != tr_e; tr_i++) { if (is_acc_trans(**tr_i, *va_i)) LT.push_back(*tr_i); } } acc_set.push_back(LT); LT.erase(LT.begin(), LT.end()); } } } bool ALT_graph_t::tr_implies(ALT_gba_trans_t *p_T1, ALT_gba_trans_t *p_T2) { // T1 => T2 if (p_T1->p_to != p_T2->p_to) return(false); if (!LTL_subset_label(p_T1->t_label, p_T2->t_label)) return(false); list ::iterator ac_b, ac_e, ac_i; ac_b = vwaa_accept_nodes.begin(); ac_e = vwaa_accept_nodes.end(); for (ac_i = ac_b; ac_i != ac_e; ac_i++) { if (is_acc_trans(*p_T2, *ac_i)) { if (!is_acc_trans(*p_T1, *ac_i)) { return(false); } } } return(true); } bool equiv_ALT_gba_node_ts(ALT_gba_node_t *p_N1, ALT_gba_node_t *p_N2) { list::iterator a1_b, a1_e, a1_i, a2_b, a2_e, a2_i; if (p_N1->adj.size() != p_N2->adj.size()) return(false); a1_b = p_N1->adj.begin(); a1_e = p_N1->adj.end(); a2_b = p_N2->adj.begin(); a2_e = p_N2->adj.end(); for (a1_i = a1_b; a1_i != a1_e; a1_i++) { for (a2_i = a2_b; a2_i != a2_e; a2_i++) { if ((*a1_i)->p_to == (*a2_i)->p_to) { if (LTL_equiv_labels((*a1_i)->t_label, (*a2_i)->t_label)) { break; } } } if (a2_i == a2_e) return(false); } return(true); } void ALT_graph_t::simp_gba_trans(ALT_gba_node_t *p_N) { list::iterator t_i1, t_i2, t_pom, t_b, t_e, t_i; list del_trans; list >::iterator sas_b, sas_e, sas_i; sas_b = acc_set.begin(); sas_e = acc_set.end(); t_i1 = p_N->adj.begin(); while (t_i1 != p_N->adj.end()) { t_i2 = p_N->adj.begin(); while (t_i2 != p_N->adj.end()) { if (t_i1 == t_i2) { t_i2++; continue; } if ((*t_i1)->p_to != (*t_i2)->p_to) { t_i2++; continue; } if (!LTL_subset_label((*t_i1)->t_label, (*t_i2)->t_label)) { t_i2++; continue; } for (sas_i = sas_b; sas_i != sas_e; sas_i++) { t_b = sas_i->begin(); t_e = sas_i->end(); t_pom = find(t_b, t_e, *t_i2); if (t_pom != t_e) { t_pom = find(t_b, t_e, *t_i1); if (t_pom == t_e) break; } } if (sas_i == sas_e) { del_trans.push_back(*t_i2); t_pom = t_i2; t_i2++; p_N->adj.erase(t_pom); } else { t_i2++; } } t_i1++; } t_b = del_trans.begin(); t_e = del_trans.end(); for (t_i = t_b; t_i != t_e; t_i++) { for (sas_i = sas_b; sas_i != sas_e; sas_i++) { t_pom = find(sas_i->begin(), sas_i->end(), *t_i); if (t_pom != sas_i->end()) { sas_i->erase(t_pom); } } delete *t_i; } } /*void ALT_graph_t::simp_ALT_gba_node_ts() { }*/ void ALT_graph_t::simplify_GBA() { list::iterator nl_b, nl_e, nl_i, nl_i1; list::iterator tr_b, tr_e, tr_i, tr_i1, tr_i2; list *p_adj; nl_b = gba_node_list.begin(); nl_e = gba_node_list.end(); /* Odstraneni redundantnich hran */ for (nl_i = nl_b; nl_i != nl_e; nl_i++) { p_adj = &((*nl_i)->adj); for (tr_i = p_adj->begin(); tr_i != p_adj->end(); tr_i++) { tr_i1 = p_adj->begin(); while (tr_i1 != p_adj->end()) { if (tr_i == tr_i1) { tr_i1++; continue; } if (tr_implies(*tr_i, *tr_i1)) { tr_i2 = tr_i1; tr_i2++; delete *tr_i1; p_adj->erase(tr_i1); tr_i1 = tr_i2; } else { tr_i1++; } } } } /* spojeni ekvivalentnich stavu */ map old_name_list; // stare jmeno, novy uzel map::iterator on_f; set new_init_nodes; list equiv_states, old_node_list; list new_node_list; list::iterator eq_b, eq_e, eq_i; list::iterator nn_b, nn_e, nn_i; //list::iterator tr_b, tr_e, tr_i; ALT_gba_node_t *p_N, *p_N1; ALT_gba_trans_t *p_Tr; timer = 1; for (nl_i = nl_b; nl_i != nl_e; nl_i++) { on_f = old_name_list.find((*nl_i)->name); if (on_f != old_name_list.end()) continue; equiv_states.push_back(*nl_i); for (nl_i1 = nl_b; nl_i1 != nl_e; nl_i1++) { if (nl_i == nl_i1) continue; if (equiv_ALT_gba_node_ts(*nl_i, *nl_i1)) { equiv_states.push_back(*nl_i1); } } p_N = new ALT_gba_node_t; p_N->name = timer; timer++; eq_b = equiv_states.begin(); eq_e = equiv_states.end(); for (eq_i = eq_b; eq_i != eq_e; eq_i++) { old_name_list[(*eq_i)->name] = p_N; } old_node_list.push_back(*eq_b); new_node_list.push_back(p_N); equiv_states.erase(eq_b, eq_e); } //if (new_node_list.size() == ALT_gba_node_t_list.size()) return; nn_b = old_node_list.begin(); nn_e = old_node_list.end(); for (nn_i = nn_b; nn_i != nn_e; nn_i++) { p_N = old_name_list[(*nn_i)->name]; tr_b = (*nn_i)->adj.begin(); tr_e = (*nn_i)->adj.end(); for (tr_i = tr_b; tr_i != tr_e; tr_i++) { p_Tr = new ALT_gba_trans_t; p_Tr->p_from = p_N; p_Tr->p_to = old_name_list[(*tr_i)->p_to->name]; p_Tr->t_label = (*tr_i)->t_label; p_N->adj.push_back(p_Tr); } } nn_b = gba_init_nodes.begin(); nn_e = gba_init_nodes.end(); for (nn_i = nn_b; nn_i != nn_e; nn_i++) { new_init_nodes.insert(old_name_list[(*nn_i)->name]); } /* doplneni akceptujicich hran */ set new_acc_trans; list > new_acc_set; list >::iterator las_b, las_e, las_i; list::iterator as_b, as_e, as_i; list >::iterator ass_b, ass_e, ass_i; ass_b = acc_set.begin(); ass_e = acc_set.end(); for (ass_i = ass_b; ass_i != ass_e; ass_i++) { as_b = ass_i->begin(); as_e = ass_i->end(); for (as_i = as_b; as_i != as_e; as_i++) { p_N = old_name_list[(*as_i)->p_from->name]; p_N1 = old_name_list[(*as_i)->p_to->name]; tr_b = p_N->adj.begin(); tr_e = p_N->adj.end(); for (tr_i = tr_b; tr_i != tr_e; tr_i++) { if ( ((*tr_i)->p_to == p_N1) && LTL_equiv_labels((*as_i)->t_label, (*tr_i)->t_label) ) { new_acc_trans.insert(*tr_i); //break; } } } new_acc_set.push_back(new_acc_trans); new_acc_trans.erase(new_acc_trans.begin(), new_acc_trans.end()); } /* zapsani noveho grafu */ set::iterator sn_b, sn_e, sn_i; set::iterator st_b, st_e, st_i; list new_acc_trans_list; for (nl_i = nl_b; nl_i != nl_e; nl_i++) { delete *nl_i; } gba_node_list.erase(nl_b, nl_e); acc_set.erase(acc_set.begin(), acc_set.end()); gba_init_nodes.erase(gba_init_nodes.begin(), gba_init_nodes.end()); gba_node_list = new_node_list; sn_b = new_init_nodes.begin(); sn_e = new_init_nodes.end(); for (sn_i = sn_b; sn_i != sn_e; sn_i++) { gba_init_nodes.push_back(*sn_i); } las_b = new_acc_set.begin(); las_e = new_acc_set.end(); for (las_i = las_b; las_i != las_e; las_i++) { st_b = las_i->begin(); st_e = las_i->end(); for (st_i = st_b; st_i != st_e; st_i++) { new_acc_trans_list.push_back(*st_i); } acc_set.push_back(new_acc_trans_list); new_acc_trans_list.erase(new_acc_trans_list.begin(), new_acc_trans_list.end()); } } bool eq_trans(const list& T1, const list& T2) { list::const_iterator t1_b, t1_e, t1_i, t2_b, t2_e, t2_i; if (T1.size() != T2.size()) return(false); t1_b = T1.begin(); t1_e = T1.end(); t2_b = T2.begin(); t2_e = T2.end(); for (t1_i = t1_b; t1_i != t1_e; t1_i++) { for (t2_i = t2_b; t2_i != t2_e; t2_i++) { if ((t1_i->target == t2_i->target) && LTL_equiv_labels(t1_i->t_label, t2_i->t_label) ) { break; } } if (t2_i == t2_e) return(false); } for (t2_i = t2_b; t2_i != t2_e; t2_i++) { for (t1_i = t1_b; t1_i != t1_e; t1_i++) { if ((t1_i->target == t2_i->target) && LTL_equiv_labels(t1_i->t_label, t2_i->t_label) ) { break; } } if (t1_i == t1_e) return(false); } return(true); } void ALT_graph_t::sim_BA_edges() { list::iterator nl_b, nl_e, nl_i; list::iterator tr_i, tr_j, tr_k; nl_b = ba_node_list.begin(); nl_e = ba_node_list.end(); for (nl_i = nl_b; nl_i != nl_e; nl_i++) { tr_i = (*nl_i)->adj.begin(); while (tr_i != (*nl_i)->adj.end()) { tr_j = (*nl_i)->adj.begin(); while (tr_j != (*nl_i)->adj.end()) { if (tr_j == tr_i) { tr_j++; continue; } if ((tr_i->target == tr_j->target) && LTL_subset_label(tr_i->t_label, tr_j->t_label)) { tr_k = tr_j; tr_j++; (*nl_i)->adj.erase(tr_k); } else { tr_j++; } } tr_i++; } } } void ALT_graph_t::simplify_BA() { sim_BA_edges(); /* spojeni ekvivalentnich stavu */ list::iterator nl_b, nl_e, nl_i, nl_j; list::iterator tr_b, tr_e, tr_i; list > list_equiv_nodes; list >::iterator len_b, len_e, len_i; list equiv_nodes; list::iterator en_b, en_e, en_i; list::iterator acn_b, acn_e, acn_f, inn_b, inn_e, inn_f; list new_node_list, new_init_nodes, new_accept_nodes; set zpracovano; set::iterator zp_f; bool acc_i, acc_j; nl_b = ba_node_list.begin(); nl_e = ba_node_list.end(); acn_b = ba_accept_nodes.begin(); acn_e = ba_accept_nodes.end(); inn_b = ba_init_nodes.begin(); inn_e = ba_init_nodes.end(); for (nl_i = nl_b; nl_i != nl_e; nl_i++) { zp_f = zpracovano.find(*nl_i); if (zp_f != zpracovano.end()) continue; zpracovano.insert(*nl_i); equiv_nodes.erase(equiv_nodes.begin(), equiv_nodes.end()); equiv_nodes.push_back(*nl_i); acn_f = find(acn_b, acn_e, *nl_i); acc_i = (acn_f != acn_e); for (nl_j = nl_i, nl_j++; nl_j != nl_e; nl_j++) { zp_f = zpracovano.find(*nl_j); if (zp_f != zpracovano.end()) continue; acn_f = find(acn_b, acn_e, *nl_j); acc_j = (acn_f != acn_e); if (acc_i != acc_j) continue; if (eq_trans((*nl_i)->adj, (*nl_j)->adj)) { zpracovano.insert(*nl_j); equiv_nodes.push_back(*nl_j); } } list_equiv_nodes.push_back(equiv_nodes); } if (list_equiv_nodes.size() == ba_node_list.size()) return; /* */ map old_name_list; ALT_ba_node_t *p_N, *p_N1; ALT_ba_trans_t Tr; int i = 1; len_b = list_equiv_nodes.begin(); len_e = list_equiv_nodes.end(); for (len_i = len_b; len_i != len_e; len_i++, i++) { p_N = new ALT_ba_node_t; p_N->name = i; p_N->p_old = 0; new_node_list.push_back(p_N); en_b = len_i->begin(); en_e = len_i->end(); for (en_i = en_b; en_i != en_e; en_i++) { old_name_list[(*en_i)->name] = p_N; } } for (len_i = len_b; len_i != len_e; len_i++) { en_b = len_i->begin(); en_e = len_i->end(); p_N = old_name_list[(*en_b)->name]; tr_b = (*en_b)->adj.begin(); tr_e = (*en_b)->adj.end(); for (tr_i = tr_b; tr_i != tr_e; tr_i++) { p_N1 = old_name_list[tr_i->target->name]; Tr.target = p_N1; Tr.t_label = tr_i->t_label; p_N->adj.push_back(Tr); } acn_f = find(acn_b, acn_e, *en_b); if (acn_f != acn_e) new_accept_nodes.push_back(p_N); for (en_i = en_b; en_i != en_e; en_i++) { inn_f = find(inn_b, inn_e, *en_i); if (inn_f != inn_e) { new_init_nodes.push_back(p_N); break; } } } /* Zapsani noveho grafu */ for (nl_i = nl_b; nl_i != nl_e; nl_i++) { delete (*nl_i); } ba_node_list = new_node_list; ba_init_nodes = new_init_nodes; ba_accept_nodes = new_accept_nodes; sim_BA_edges(); } void ALT_graph_t::simplify_on_the_fly(bool s) { simp_GBA = s; } void ALT_graph_t::vypis_GBA() { list::const_iterator nl_b, nl_e, nl_i; list::const_iterator tr_b, tr_e, tr_i; list ::const_iterator vn_b, vn_e, vn_i; LTL_label_t::const_iterator lf_b, lf_e, lf_i; bool b, b1; int node_counter = 0, trans_counter = 0; cout << endl; cout << "Initial: {"; nl_b = gba_init_nodes.begin(); nl_e = gba_init_nodes.end(); b = false; for (nl_i = nl_b; nl_i != nl_e; nl_i++) { if (b) { cout << ", "; } else { b = true; } cout << (*nl_i)->name; } cout << "}" << endl; nl_b = gba_node_list.begin(); nl_e = gba_node_list.end(); for (nl_i = nl_b; nl_i != nl_e; nl_i++) { node_counter++; if ((*nl_i)->node_label.size() > 0) { cout << (*nl_i)->name << ": {"; vn_b = (*nl_i)->node_label.begin(); vn_e = (*nl_i)->node_label.end(); b = false; for (vn_i = vn_b; vn_i != vn_e; vn_i++) { if (b) { cout << ", "; } else { b = true; } cout << (*vn_i)->label; } cout << "} -> {"; } else { cout << (*nl_i)->name << " -> {"; } tr_b = (*nl_i)->adj.begin(); tr_e = (*nl_i)->adj.end(); b = false; for (tr_i = tr_b; tr_i != tr_e; tr_i++) { trans_counter++; if (b) { cout << ", "; } else { b = true; } cout << "(<"; lf_b = (*tr_i)->t_label.begin(); lf_e = (*tr_i)->t_label.end(); b1 = false; for (lf_i = lf_b; lf_i != lf_e; lf_i++) { if (b1) { cout << ", "; } else { b1 = true; } cout << *lf_i; } cout << "> - " << (*tr_i)->p_to->name; cout << ")"; } cout << "}" << endl; } list >::iterator aa_b, aa_e, aa_i; list::iterator a_b, a_e, a_i; cout << "Accept sets of set of transitions:" << endl; aa_b = acc_set.begin(); aa_e = acc_set.end(); for (aa_i = aa_b; aa_i != aa_e; aa_i++) { cout << "{"; a_b = aa_i->begin(); a_e = aa_i->end(); b = false; for (a_i = a_b; a_i != a_e; a_i++) { if (b) { cout << ", "; } else { b = true; } cout << "(" << (*a_i)->p_from->name; cout << " - <"; lf_b = (*a_i)->t_label.begin(); lf_e = (*a_i)->t_label.end(); b1 = false; for (lf_i = lf_b; lf_i != lf_e; lf_i++) { if (b1) { cout << ", "; } else { b1 = true; } cout << *lf_i; } cout << "> -> " << (*a_i)->p_to->name; cout << ")"; } cout << "}" << endl; } cout << endl; cout << "nodes: " << node_counter << "; transitions: " << trans_counter << "; initial: " << gba_init_nodes.size() << "; accept sets: " << acc_set.size() << endl; } ALT_ba_node_t* ALT_graph_t::add_ba_node(ALT_gba_node_t *p_gN, int citac) { list::iterator nl_b, nl_e, nl_i; ALT_ba_node_t *p_N; nl_b = ba_node_list.begin(); nl_e = ba_node_list.end(); for (nl_i = nl_b; nl_i != nl_e; nl_i++) { if (((*nl_i)->p_old == p_gN) && ((*nl_i)->citac == citac)) break; } if (nl_i == nl_e) { p_N = new ALT_ba_node_t; p_N->name = timer; timer++; p_N->citac = citac; p_N->p_old = p_gN; ba_node_list.push_back(p_N); return(p_N); } else { return(*nl_i); } } void ALT_graph_t::add_ba_trans(int j, ALT_gba_trans_t *p_gt, ALT_ba_trans_t& Tr) { list >::iterator llt_b, llt_e, llt_i; list::iterator lt_e, lt_i; int i, r; r = acc_set.size(); if ((j > r) || (j < 0)) return; llt_b = acc_set.begin(); llt_e = acc_set.end(); if (j != r) { i = 0; for (llt_i = llt_b; i < j; llt_i++, i++) ; //llt_i++; i++; for (; llt_i != llt_e; llt_i++, i++) { lt_e = llt_i->end(); lt_i = find(llt_i->begin(), lt_e, p_gt); if (lt_i == lt_e) break; } Tr.target = add_ba_node(p_gt->p_to, i); } else { i = 0; for (llt_i = llt_b; llt_i != llt_e; llt_i++, i++) { lt_e = llt_i->end(); lt_i = find(llt_i->begin(), lt_e, p_gt); if (lt_i == lt_e) break; } Tr.target = add_ba_node(p_gt->p_to, i); } Tr.t_label = p_gt->t_label; } void ALT_graph_t::degeneralize() { list::const_iterator ln_b, ln_e, ln_i; list::const_iterator gt_b, gt_e, gt_i; list::iterator ba_b, ba_i; int s, t;; ALT_ba_node_t *p_bN; ALT_ba_trans_t Tr; timer = 1; s = acc_set.size(); ln_b = gba_init_nodes.begin(); ln_e = gba_init_nodes.end(); for (ln_i = ln_b; ln_i != ln_e; ln_i++) { p_bN = new ALT_ba_node_t; p_bN->name = timer; timer++; p_bN->citac = 0; p_bN->p_old = (*ln_i); ba_node_list.push_back(p_bN); ba_init_nodes.push_back(p_bN); } ba_b = ba_node_list.begin(); for (ba_i = ba_b; ba_i != ba_node_list.end(); ba_i++) { t = (*ba_i)->citac; if (t == s) { ba_accept_nodes.push_back(*ba_i); } gt_b = (*ba_i)->p_old->adj.begin(); gt_e = (*ba_i)->p_old->adj.end(); for (gt_i = gt_b; gt_i != gt_e; gt_i++) { add_ba_trans(t, *gt_i, Tr); (*ba_i)->adj.push_back(Tr); } } } void ALT_graph_t::vypis_BA() { list::const_iterator nl_b, nl_e, nl_i; list::const_iterator tr_b, tr_e, tr_i; LTL_label_t::const_iterator tl_b, tl_e, tl_i; bool b, b1; int trans_counter = 0; cout << "Initial: {"; b = false; nl_b = ba_init_nodes.begin(); nl_e = ba_init_nodes.end(); for (nl_i = nl_b; nl_i != nl_e; nl_i++) { if (b) { cout << ", "; } else { b = true; } cout << (*nl_i)->name; } cout << "}" << endl; nl_b = ba_node_list.begin(); nl_e = ba_node_list.end(); for (nl_i = nl_b; nl_i != nl_e; nl_i++) { cout << (*nl_i)->name; cout << ":"; if ((*nl_i)->p_old != 0) { cout << " (" << (*nl_i)->p_old->name << ", "; cout << (*nl_i)->citac << ")"; } cout << " -> {"; b = false; tr_b = (*nl_i)->adj.begin(); tr_e = (*nl_i)->adj.end(); for (tr_i = tr_b; tr_i != tr_e; tr_i++) { trans_counter++; if (b) { cout << ", "; } else { b = true; } cout << "(<"; b1 = false; tl_b = tr_i->t_label.begin(); tl_e = tr_i->t_label.end(); for (tl_i = tl_b; tl_i != tl_e; tl_i++) { if (b1) { cout << ", "; } else { b1 = true; } cout << *tl_i; } cout << "> - " << tr_i->target->name << ")"; } cout << "}" << endl; } cout << "Accept: {"; b = false; nl_b = ba_accept_nodes.begin(); nl_e = ba_accept_nodes.end(); for (nl_i = nl_b; nl_i != nl_e; nl_i++) { if (b) { cout << ", "; } else { b = true; } cout << (*nl_i)->name; } cout << "}" << endl; cout << "nodes: " << ba_node_list.size() << "; transitions: " << trans_counter << "; initial: " << ba_init_nodes.size() << "; accept: " << ba_accept_nodes.size() << endl; } list ALT_graph_t::get_all_BA_nodes() const { return(ba_node_list); } list ALT_graph_t::get_init_BA_nodes() const { return(ba_init_nodes); } list ALT_graph_t::get_accept_BA_nodes() const { return(ba_accept_nodes); }