tgbamask: implement a build_tgba_mask_acc_ignore() function.

* src/tgba/tgbamask.hh (build_tgba_mask_acc_ignore): New function.
(tgba_mask::wanted): Take an acc argument.
* src/tgba/tgbamask.cc: Implement the above.
* src/tgbatest/maskacc.cc, src/tgbatest/maskacc.test: New files.
* src/tgbatest/Makefile.am: Add them.
This commit is contained in:
Alexandre Duret-Lutz 2014-03-27 18:35:41 +01:00
parent a828662be6
commit 425e8bb37a
6 changed files with 215 additions and 47 deletions

View file

@ -76,49 +76,8 @@ namespace spot
transitions::const_iterator it_;
};
class tgba_mask_keep: public tgba_mask
{
const state_set& mask_;
public:
tgba_mask_keep(const tgba* masked,
const state_set& mask,
const state* init)
: tgba_mask(masked, init),
mask_(mask)
{
}
bool wanted(const state* s) const
{
state_set::const_iterator i = mask_.find(s);
return i != mask_.end();
}
};
class tgba_mask_ignore: public tgba_mask
{
const state_set& mask_;
public:
tgba_mask_ignore(const tgba* masked,
const state_set& mask,
const state* init)
: tgba_mask(masked, init),
mask_(mask)
{
}
bool wanted(const state* s) const
{
state_set::const_iterator i = mask_.find(s);
return i == mask_.end();
}
};
}
tgba_mask::tgba_mask(const tgba* masked,
const state* init)
: tgba_proxy(masked),
@ -155,19 +114,79 @@ namespace spot
for (auto it: original_->succ(state))
{
const spot::state* s = it->current_state();
if (!wanted(s))
bdd acc = it->current_acceptance_conditions();
if (!wanted(s, acc))
{
s->destroy();
continue;
}
transition t = { s,
it->current_condition(),
it->current_acceptance_conditions() };
res->trans_.push_back(t);
res->trans_.emplace_back(transition {s, it->current_condition(), acc});
}
return res;
}
namespace
{
class tgba_mask_keep: public tgba_mask
{
const state_set& mask_;
public:
tgba_mask_keep(const tgba* masked,
const state_set& mask,
const state* init)
: tgba_mask(masked, init),
mask_(mask)
{
}
bool wanted(const state* s, const bdd&) const
{
state_set::const_iterator i = mask_.find(s);
return i != mask_.end();
}
};
class tgba_mask_ignore: public tgba_mask
{
const state_set& mask_;
public:
tgba_mask_ignore(const tgba* masked,
const state_set& mask,
const state* init)
: tgba_mask(masked, init),
mask_(mask)
{
}
bool wanted(const state* s, const bdd&) const
{
state_set::const_iterator i = mask_.find(s);
return i == mask_.end();
}
};
class tgba_mask_acc_ignore: public tgba_mask
{
const bdd& mask_;
public:
tgba_mask_acc_ignore(const tgba* masked,
const bdd& mask,
const state* init)
: tgba_mask(masked, init),
mask_(mask)
{
}
bool wanted(const state*, const bdd& acc) const
{
return (acc & mask_) == bddfalse;
}
};
}
const tgba*
build_tgba_mask_keep(const tgba* to_mask,
@ -185,4 +204,12 @@ namespace spot
return new tgba_mask_ignore(to_mask, to_ignore, init);
}
const tgba*
build_tgba_mask_acc_ignore(const tgba* to_mask,
const bdd to_ignore,
const state* init)
{
return new tgba_mask_acc_ignore(to_mask, to_ignore, init);
}
}

View file

@ -21,6 +21,7 @@
# define SPOT_TGBA_TGBAMASK_HH
#include "tgbaproxy.hh"
#include "bdd.h"
namespace spot
{
@ -50,7 +51,7 @@ namespace spot
virtual tgba_succ_iterator*
succ_iter(const state* local_state) const;
virtual bool wanted(const state* s) const = 0;
virtual bool wanted(const state* s, const bdd& acc) const = 0;
protected:
const state* init_;
@ -78,6 +79,23 @@ namespace spot
const state_set& to_ignore,
const state* init = 0);
/// \ingroup tgba_on_the_fly_algorithms
/// \brief Mask a TGBA, rejecting some acceptance set of transitions.
///
/// This will ignore all transitions labeled by the acceptance ACC
/// such that ACC & TO_IGNORE != bddfalse. The initial state can
/// optionally be reset to \a init.
///
/// Note that the acceptance condition of the automaton (i.e. the
/// set of all acceptance set) is not changed, because so far this
/// function is only needed in graph algorithms that do not call
/// all_acceptance_conditions().
SPOT_API const tgba*
build_tgba_mask_acc_ignore(const tgba* to_mask,
const bdd to_ignore,
const state* init = 0);
}
#endif // SPOT_TGBA_TGBAMASK_HH