You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
226 lines
6.3 KiB
226 lines
6.3 KiB
/*
|
|
* This file is part of the program ltl2dstar (http://www.ltl2dstar.de/).
|
|
* Copyright (C) 2005-2007 Joachim Klein <j.klein@ltl2dstar.de>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
|
|
#ifndef STUTTERSENSITIVENESSINFORMATION_H
|
|
#define STUTTERSENSITIVENESSINFORMATION_H
|
|
|
|
/** @file
|
|
* Provide class StutterSensitivenessInformation
|
|
*/
|
|
|
|
#include "NBAStutterClosure.hpp"
|
|
#include "NBAAnalysis.hpp"
|
|
#include "LTLFormula.hpp"
|
|
|
|
#include "common/TimeKeeper.hpp"
|
|
|
|
/** Calculate and store information about which symbols from 2^APSet
|
|
* are insensitive to stuttering.
|
|
*/
|
|
class StutterSensitivenessInformation {
|
|
public:
|
|
/** Constructor */
|
|
StutterSensitivenessInformation() :
|
|
_completelyStutterInsensitive(false),
|
|
_partiallyStutterInsensitive(false),
|
|
_hasCheckedLTL(false),
|
|
_hasCheckedNBAs(false) {}
|
|
|
|
/** Check the LTLFormula syntacticly for
|
|
* stutter insensitiveness */
|
|
void checkLTL(LTLFormula_ptr& ltl) {
|
|
if (hasTimekeeping()) {getTimeKeeper().start();}
|
|
if (ltl->hasNextStep()) {
|
|
_completelyStutterInsensitive=false;
|
|
_partiallyStutterInsensitive=false;
|
|
} else {
|
|
_completelyStutterInsensitive=true;
|
|
_partiallyStutterInsensitive=false;
|
|
}
|
|
|
|
_hasCheckedLTL=true;
|
|
|
|
if (hasTimekeeping()) {getTimeKeeper().stop();}
|
|
}
|
|
|
|
|
|
/** Check for partial stutter insensitiveness using
|
|
* the nba and the complement nba */
|
|
template <class NBA_t>
|
|
void checkNBAs(NBA_t& nba,
|
|
NBA_t& nba_complement) {
|
|
if (hasTimekeeping()) {getTimeKeeper().start();}
|
|
APSet_cp apset=nba.getAPSet_cp();
|
|
|
|
bool nba_is_smaller=(nba.size() < nba_complement.size());
|
|
|
|
if (_printInfo) {
|
|
std::cerr << "Checking for insensitiveness" << std::endl;
|
|
}
|
|
bool one_insensitive=false;
|
|
bool all_insensitive=true;
|
|
for (APSet::element_iterator it=apset->all_elements_begin();
|
|
it!=apset->all_elements_end();
|
|
++it) {
|
|
APElement elem(*it);
|
|
|
|
if (_partiallyInsensitive.get(elem)) {
|
|
// don't recheck something we already now is stutter insensitive
|
|
one_insensitive=true;
|
|
continue;
|
|
}
|
|
|
|
if (_printInfo) {
|
|
std::cerr << "Checking " << elem.toString(*apset) << ": ";
|
|
std::cerr.flush();
|
|
}
|
|
|
|
bool insensitive;
|
|
if (nba_is_smaller) {
|
|
insensitive=is_stutter_insensitive(nba, nba_complement, elem);
|
|
} else {
|
|
insensitive=is_stutter_insensitive(nba_complement, nba, elem);
|
|
}
|
|
if (insensitive) {
|
|
_partiallyInsensitive.set(elem);
|
|
one_insensitive=true;
|
|
if (_printInfo) {
|
|
std::cerr << "+" << std::endl;
|
|
}
|
|
} else {
|
|
all_insensitive=false;
|
|
if (_printInfo) {
|
|
std::cerr << "-" << std::endl;
|
|
}
|
|
}
|
|
}
|
|
|
|
_hasCheckedNBAs=true;
|
|
_partiallyStutterInsensitive=one_insensitive;
|
|
|
|
if (hasTimekeeping()) {getTimeKeeper().stop();}
|
|
}
|
|
|
|
/** Check for partial stutter insensitiveness for a LTL formula.
|
|
* @param ltl the LTL formula
|
|
* @param llt2nba the LTL2NBA translator, has to provide function ltl2nba(ltl)
|
|
*/
|
|
template <class LTL2NBA_Calc>
|
|
void checkPartial(LTLFormula& ltl,
|
|
LTL2NBA_Calc& ltl2nba) {
|
|
if (hasTimekeeping()) {getTimeKeeper().start();}
|
|
checkNBAs(*ltl2nba.ltl2nba(ltl, true),
|
|
*ltl2nba.ltl2nba(*ltl.negate()->toPNF(), true));
|
|
if (hasTimekeeping()) {getTimeKeeper().stop();}
|
|
}
|
|
|
|
/** Check for partial stutter insensitiveness for a LTL formula, using an
|
|
* already calculated NBA.
|
|
* @param nba an NBA for the positive formula
|
|
* @param ltl_neg the negated LTL formula (in PNF)
|
|
* @param llt2nba the LTL2NBA translator, has to provide function ltl2nba(ltl)
|
|
*/
|
|
template <class NBA_t, class LTL2NBA_Calc>
|
|
void checkPartial(NBA_t& nba,
|
|
LTLFormula& ltl_neg,
|
|
LTL2NBA_Calc& ltl2nba) {
|
|
if (hasTimekeeping()) {getTimeKeeper().start();}
|
|
checkNBAs(nba, *ltl2nba.ltl2nba(ltl_neg));
|
|
if (hasTimekeeping()) {getTimeKeeper().stop();}
|
|
}
|
|
|
|
|
|
|
|
/** Return true iff all symbols are completely stutter
|
|
* insensitive. */
|
|
bool isCompletelyInsensitive() const {
|
|
return _completelyStutterInsensitive;
|
|
}
|
|
|
|
/** Return true iff some (or all) symbols are stutter insensitive,
|
|
* result is undefined if isCompletelyInsensitive()==true
|
|
*/
|
|
bool isPartiallyInsensitive() const {
|
|
return _partiallyStutterInsensitive;
|
|
}
|
|
|
|
/** Get the set of the stutter insensitive symbols from 2^APSet */
|
|
const BitSet& getPartiallyInsensitiveSymbols() const {
|
|
return _partiallyInsensitive;
|
|
}
|
|
|
|
/** shared_ptr */
|
|
typedef std::shared_ptr<StutterSensitivenessInformation> ptr;
|
|
|
|
/** Static, do Timekeeping? */
|
|
static bool hasTimekeeping() {
|
|
return _enableTimekeeping;
|
|
}
|
|
|
|
/** Static, enable Timekeeping? */
|
|
static void enableTimekeeping() {
|
|
_enableTimekeeping=true;
|
|
}
|
|
|
|
/** Static, enable printing of verbose information */
|
|
static void enablePrintInfo() {
|
|
_printInfo=true;
|
|
}
|
|
|
|
/** Get the timekeeper object */
|
|
static TimeKeeper& getTimeKeeper() {
|
|
return _timekeeper;
|
|
}
|
|
|
|
|
|
private:
|
|
bool _completelyStutterInsensitive;
|
|
bool _partiallyStutterInsensitive;
|
|
|
|
bool _hasCheckedLTL;
|
|
bool _hasCheckedNBAs;
|
|
BitSet _partiallyInsensitive;
|
|
|
|
static bool _enableTimekeeping;
|
|
static bool _printInfo;
|
|
static TimeKeeper _timekeeper;
|
|
|
|
|
|
// -- private member functions
|
|
|
|
/** Check that symbol label is stutter insensitive,
|
|
* using nba and complement_nba */
|
|
template <class NBA_t>
|
|
bool is_stutter_insensitive(NBA_t& nba, NBA_t& nba_complement, APElement label) {
|
|
typedef std::shared_ptr<NBA_t> NBA_ptr;
|
|
|
|
NBA_ptr stutter_closed_nba=NBAStutterClosure::stutter_closure(nba, label);
|
|
|
|
NBA_ptr product=NBA_t::product_automaton(*stutter_closed_nba, nba_complement);
|
|
|
|
NBAAnalysis<NBA_t> analysis_product(*product);
|
|
bool empty=analysis_product.emptinessCheck();
|
|
// std::cerr << "NBA is " << (empty ? "empty" : "not empty") << std::endl;
|
|
|
|
return empty;
|
|
}
|
|
};
|
|
|
|
|
|
#endif
|