diff --git a/src/ltltest/reduc0.test b/src/ltltest/reduc0.test index 2a3c9e456..dd3a06787 100755 --- a/src/ltltest/reduc0.test +++ b/src/ltltest/reduc0.test @@ -31,3 +31,7 @@ run 0 ../reduc 0 '(Xf W 0) | X(f W 0)' 'XGf' # valid if r has a non-empty language. run 0 ../reduc 0 '{a[*];{b && !b}}' run 0 ../reduc 0 '!{a[*];{b && !b}}' + +# Triggered an assert before +run 0 ../reduc 0 '(a | (Xa M a))' +run 0 ../reduc 0 '(b xor (Xb U b)) <-> e' diff --git a/src/ltlvisit/simplify.cc b/src/ltlvisit/simplify.cc index a3e24042a..f5e55b79f 100644 --- a/src/ltlvisit/simplify.cc +++ b/src/ltlvisit/simplify.cc @@ -18,7 +18,7 @@ // along with this program. If not, see . #include -//#define TRACE +// #define TRACE #ifdef TRACE #define trace std::cerr #else @@ -2903,18 +2903,19 @@ namespace spot // Make a second pass to check if the "a" // terms can be used to simplify "Xa W b", // "Xa U b", "b | X(b R a)", or "b | X(b M a)". + multop::vec resorig(*res); for (unsigned n = 0; n < s; ++n) { - if (!(*res)[n]) + const formula* x = resorig[n]; + if (!x) continue; - fmap_t::const_iterator gs = - wuset.find((*res)[n]); + fmap_t::const_iterator gs = wuset.find(x); if (gs == wuset.end()) continue; for (unsigned pos: gs->second) { - const binop* wu = is_binop((*res)[pos]); + const binop* wu = is_binop(resorig[pos]); if (wu) { // a & (Xa W b) = b R a @@ -2925,23 +2926,26 @@ namespace spot down_cast(wu->first()); const formula* a = xa->child()->clone(); const formula* b = wu->second()->clone(); - wu->destroy(); (*res)[pos] = binop::instance(t, b, a); } else { // a & (b | X(b R a)) = b R a // a & (b | X(b M a)) = b M a - wu = is_bXbRM((*res)[pos]); + wu = is_bXbRM(resorig[pos]); assert(wu); wu->clone(); - (*res)[pos]->destroy(); (*res)[pos] = wu; } // Remember to kill "a". tokill[n] = true; } } + + for (unsigned n = 0; n < s; ++n) + if (resorig[n] != (*res)[n]) + resorig[n]->destroy(); + // Make third pass to search for terms 'a' // that also appears as 'XGa'. Replace them // by 'Ga' and delete XGa. @@ -3629,9 +3633,10 @@ namespace spot // Make a second pass to check if we can // remove all instance of XF(a). unsigned allofthem = xfset.size(); + multop::vec resorig(*res); for (unsigned n = 0; n < s; ++n) - { - const formula* x = (*res)[n]; + { + const formula* x = resorig[n]; if (!x) continue; fset_t::const_iterator f = xfset.find(x); @@ -3646,7 +3651,7 @@ namespace spot continue; for (unsigned pos: gs->second) { - const binop* rm = is_binop((*res)[pos]); + const binop* rm = is_binop(resorig[pos]); if (rm) { // a | (Xa R b) = b W a @@ -3657,23 +3662,27 @@ namespace spot down_cast(rm->first()); const formula* a = xa->child()->clone(); const formula* b = rm->second()->clone(); - rm->destroy(); (*res)[pos] = binop::instance(t, b, a); } else { // a | (b & X(b W a)) = b W a // a | (b & X(b U a)) = b U a - rm = is_bXbWU((*res)[pos]); + rm = is_bXbWU(resorig[pos]); assert(rm); rm->clone(); - (*res)[pos]->destroy(); (*res)[pos] = rm; } // Remember to kill "a". tokill[n] = true; } } + + for (unsigned n = 0; n < s; ++n) + if (resorig[n] != (*res)[n]) + resorig[n]->destroy(); + + // If we can remove all of them... if (allofthem == 0) // Make third pass to search for terms 'a'