Add implication-based rewritings from Babiak et al. (TACAS'12)
* src/ltlvisit/simplify.cc: Implement them here, and augment them to support M, and W operators. * src/ltltest/reduccmp.test: Add some tests. * doc/tl/tl.tex (Simplifications Based on Implications): Document these rules. * doc/tl/tl.bib (babiak.12.tacas): New entry.
This commit is contained in:
parent
ed0dd0b48d
commit
212c7ebdd7
4 changed files with 124 additions and 5 deletions
|
|
@ -1272,9 +1272,16 @@ namespace spot
|
|||
}
|
||||
// if a => b, then a U (b U c) = (b U c)
|
||||
// if a => b, then a U (b W c) = (b W c)
|
||||
// if b => a, then a U (b U c) = (a U c)
|
||||
// if a => c, then a U (b R (c U d)) = (b R (c U d))
|
||||
// if a => c, then a U (b R (c W d)) = (b R (c W d))
|
||||
// if a => c, then a U (b M (c U d)) = (b M (c U d))
|
||||
// if a => c, then a U (b M (c W d)) = (b M (c W d))
|
||||
if (b->kind() == formula::BinOp)
|
||||
{
|
||||
binop* bo = static_cast<binop*>(b);
|
||||
// if a => b, then a U (b U c) = (b U c)
|
||||
// if a => b, then a U (b W c) = (b W c)
|
||||
if ((bo->op() == binop::U || bo->op() == binop::W)
|
||||
&& c_->implication(a, bo->first()))
|
||||
{
|
||||
|
|
@ -1282,6 +1289,32 @@ namespace spot
|
|||
result_ = b;
|
||||
return;
|
||||
}
|
||||
// if b => a, then a U (b U c) = (a U c)
|
||||
if (bo->op() == binop::U
|
||||
&& c_->implication(bo->first(), a))
|
||||
{
|
||||
result_ = recurse_destroy
|
||||
(binop::instance(binop::U,
|
||||
a, bo->second()->clone()));
|
||||
b->destroy();
|
||||
return;
|
||||
}
|
||||
// if a => c, then a U (b R (c U d)) = (b R (c U d))
|
||||
// if a => c, then a U (b R (c W d)) = (b R (c W d))
|
||||
// if a => c, then a U (b M (c U d)) = (b M (c U d))
|
||||
// if a => c, then a U (b M (c W d)) = (b M (c W d))
|
||||
if ((bo->op() == binop::R || bo->op() == binop::M)
|
||||
&& bo->second()->kind() == formula::BinOp)
|
||||
{
|
||||
binop* cd = static_cast<binop*>(bo->second());
|
||||
if ((cd->op() == binop::U || cd->op() == binop::W)
|
||||
&& c_->implication(a, cd->first()))
|
||||
{
|
||||
a->destroy();
|
||||
result_ = b;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -1317,13 +1350,30 @@ namespace spot
|
|||
if (bo->op() == binop::R
|
||||
&& c_->implication(a, bo->first()))
|
||||
{
|
||||
b->destroy();
|
||||
result_ = recurse_destroy
|
||||
(binop::instance(binop::R, a,
|
||||
bo->second()->clone()));
|
||||
b->destroy();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (a->kind() == formula::BinOp)
|
||||
{
|
||||
// if b => a then (a R c) R b = c R b
|
||||
// if b => a then (a M c) R b = c R b
|
||||
binop* bo = static_cast<binop*>(a);
|
||||
if ((bo->op() == binop::R || bo->op() == binop::M)
|
||||
&& c_->implication(b, bo->first()))
|
||||
{
|
||||
result_ = recurse_destroy
|
||||
(binop::instance(binop::R,
|
||||
bo->second()->clone(),
|
||||
b));
|
||||
a->destroy();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case binop::W:
|
||||
|
|
@ -1347,9 +1397,12 @@ namespace spot
|
|||
}
|
||||
// if a => b, then a W (b W c) = (b W c)
|
||||
// (Beware: even if a => b we do not have a W (b U c) = b U c)
|
||||
// if b => a, then a W (b U c) = (a W c)
|
||||
// if b => a, then a W (b W c) = (a W c)
|
||||
if (b->kind() == formula::BinOp)
|
||||
{
|
||||
binop* bo = static_cast<binop*>(b);
|
||||
// if a => b, then a W (b W c) = (b W c)
|
||||
if (bo->op() == binop::W
|
||||
&& c_->implication(a, bo->first()))
|
||||
{
|
||||
|
|
@ -1357,6 +1410,17 @@ namespace spot
|
|||
result_ = b;
|
||||
return;
|
||||
}
|
||||
// if b => a, then a W (b U c) = (a W c)
|
||||
// if b => a, then a W (b W c) = (a W c)
|
||||
if ((bo->op() == binop::U || bo->op() == binop::W)
|
||||
&& c_->implication(bo->first(), a))
|
||||
{
|
||||
result_ = recurse_destroy
|
||||
(binop::instance(binop::W,
|
||||
a, bo->second()->clone()));
|
||||
b->destroy();
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
@ -1400,6 +1464,21 @@ namespace spot
|
|||
return;
|
||||
}
|
||||
}
|
||||
if (a->kind() == formula::BinOp)
|
||||
{
|
||||
// if b => a then (a M c) M b = c M b
|
||||
binop* bo = static_cast<binop*>(a);
|
||||
if (bo->op() == binop::M
|
||||
&& c_->implication(b, bo->first()))
|
||||
{
|
||||
result_ = recurse_destroy
|
||||
(binop::instance(binop::M,
|
||||
bo->second()->clone(),
|
||||
b));
|
||||
a->destroy();
|
||||
return;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
trace << "bo: no inclusion-based rules matched" << std::endl;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue