Browse Source
			
			
			Added similar filters for Ltl and Csl.
			
				
		Added similar filters for Ltl and Csl.
	
		
	
			
				- Fixed similar undefined behavior for the MarkovAutomaton Csl modelchecker.
Next up: Make necessary changes to the formula parsers.
Former-commit-id: e8765fe58b
			
			
				main
			
			
		
				 9 changed files with 428 additions and 135 deletions
			
			
		- 
					211src/formula/Csl/CslFilter.h
- 
					138src/formula/Ltl/LtlFilter.h
- 
					10src/formula/Prctl/PrctlFilter.h
- 
					108src/modelchecker/csl/AbstractModelChecker.h
- 
					51src/modelchecker/csl/SparseMarkovAutomatonCslModelChecker.h
- 
					26src/modelchecker/ltl/AbstractModelChecker.h
- 
					8src/modelchecker/prctl/AbstractModelChecker.h
- 
					4src/modelchecker/prctl/SparseDtmcPrctlModelChecker.h
- 
					7src/modelchecker/prctl/SparseMdpPrctlModelChecker.h
| @ -0,0 +1,211 @@ | |||
| /* | |||
|  * CslFilter.h | |||
|  * | |||
|  *  Created on: May 7, 2014 | |||
|  *      Author: Manuel Sascha Weiand | |||
|  */ | |||
| 
 | |||
| #ifndef STORM_FORMULA_PRCTL_CSLFILTER_H_ | |||
| #define STORM_FORMULA_PRCTL_CSLFILTER_H_ | |||
| 
 | |||
| #include "src/formula/AbstractFilter.h" | |||
| #include "src/formula/Csl/AbstractCslFormula.h" | |||
| #include "src/formula/Csl/AbstractPathFormula.h" | |||
| #include "src/formula/Csl/AbstractStateFormula.h" | |||
| 
 | |||
| namespace storm { | |||
| namespace property { | |||
| namespace csl { | |||
| 
 | |||
| template <class T> | |||
| class CslFilter : storm::property::AbstractFilter<T> { | |||
| 
 | |||
| public: | |||
| 
 | |||
| 	CslFilter() : child(nullptr) { | |||
| 		// Intentionally left empty. | |||
| 	} | |||
| 
 | |||
| 	CslFilter(AbstractCslFormula* child) : child(child) { | |||
| 		// Intentionally left empty. | |||
| 	} | |||
| 
 | |||
| 	CslFilter(AbstractCslFormula* child, action::Action<T>* action) : child(child) { | |||
| 		actions.push_back(action); | |||
| 	} | |||
| 
 | |||
| 	CslFilter(AbstractCslFormula* child, std::vector<action::Action<T>*> actions) : child(child), actions(actions) { | |||
| 		// Intentionally left empty. | |||
| 	} | |||
| 
 | |||
| 	virtual ~CslFilter() { | |||
| 		actions.clear(); | |||
| 		delete child; | |||
| 	} | |||
| 
 | |||
| 	void check(AbstractModelChecker const & modelchecker) const { | |||
| 
 | |||
| 		// Write out the formula to be checked. | |||
| 		std::cout << std::endl; | |||
| 		LOG4CPLUS_INFO(logger, "Model checking formula\t" << this->toFormulaString()); | |||
| 		std::cout << "Model checking formula:\t" << this->toFormulaString() << std::endl; | |||
| 
 | |||
| 		// Do a dynamic cast to test for the actual formula type and call the correct evaluation function. | |||
| 		if(dynamic_cast<AbstractStateFormula<T>*>(child) != nullptr) { | |||
| 
 | |||
| 			// Check the formula and apply the filter actions. | |||
| 			storm::storage::BitVector result; | |||
| 
 | |||
| 			try { | |||
| 				result = evaluate(modelchecker, static_cast<AbstractStateFormula<T>*>(child)); | |||
| 			} catch (std::exception& e) { | |||
| 				std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; | |||
| 				LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); | |||
| 				std::cout << std::endl << "-------------------------------------------" << std::endl; | |||
| 
 | |||
| 				return; | |||
| 			} | |||
| 
 | |||
| 			// Now write out the result. | |||
| 
 | |||
| 			if(actions.empty()) { | |||
| 
 | |||
| 				// There is no filter action given. So provide legacy support: | |||
| 				// Return the results for all states labeled with "init". | |||
| 				LOG4CPLUS_INFO(logger, "Result for initial states:"); | |||
| 				std::cout << "Result for initial states:" << std::endl; | |||
| 				for (auto initialState : modelchecker.getModel<storm::models::AbstractModel<T>>().getInitialStates()) { | |||
| 					LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << (result.get(initialState) ? "satisfied" : "not satisfied")); | |||
| 					std::cout << "\t" << initialState << ": " << result.get(initialState) << std::endl; | |||
| 				} | |||
| 			} | |||
| 
 | |||
| 			std::cout << std::endl << "-------------------------------------------" << std::endl; | |||
| 
 | |||
| 		} | |||
| 		else if (dynamic_cast<AbstractPathFormula<T>*>(child) != nullptr) { | |||
| 
 | |||
| 			// Check the formula and apply the filter actions. | |||
| 			std::vector<T> result; | |||
| 
 | |||
| 			try { | |||
| 				result = evaluate(modelchecker, static_cast<AbstractPathFormula<T>*>(child)); | |||
| 			} catch (std::exception& e) { | |||
| 				std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; | |||
| 				LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); | |||
| 				std::cout << std::endl << "-------------------------------------------" << std::endl; | |||
| 
 | |||
| 				return; | |||
| 			} | |||
| 
 | |||
| 			// Now write out the result. | |||
| 
 | |||
| 			if(actions.empty()) { | |||
| 
 | |||
| 				// There is no filter action given. So provide legacy support: | |||
| 				// Return the results for all states labeled with "init". | |||
| 				LOG4CPLUS_INFO(logger, "Result for initial states:"); | |||
| 				std::cout << "Result for initial states:" << std::endl; | |||
| 				for (auto initialState : modelchecker.getModel<storm::models::AbstractModel<T>>().getInitialStates()) { | |||
| 					LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << result[initialState]); | |||
| 					std::cout << "\t" << initialState << ": " << result[initialState] << std::endl; | |||
| 				} | |||
| 			} | |||
| 
 | |||
| 			std::cout << std::endl << "-------------------------------------------" << std::endl; | |||
| 
 | |||
| 		} | |||
| 		else { | |||
| 			// This branch should be unreachable. If you ended up here, something strange has happened. | |||
| 			//TODO: Error here. | |||
| 		} | |||
| 	} | |||
| 
 | |||
| 	bool validate() const { | |||
| 		// Test whether the stored filter actions are consistent in relation to themselves and to the ingoing modelchecking result. | |||
| 
 | |||
| 		// Do a dynamic cast to test for the actual formula type. | |||
| 		if(dynamic_cast<AbstractStateFormula<T>*>(child) != nullptr) { | |||
| 			//TODO: Actual validation. | |||
| 		} | |||
| 		else if (dynamic_cast<AbstractPathFormula<T>*>(child) != nullptr) { | |||
| 			//TODO: Actual validation. | |||
| 		} | |||
| 		else { | |||
| 			// This branch should be unreachable. If you ended up here, something strange has happened. | |||
| 			//TODO: Error here. | |||
| 		} | |||
| 
 | |||
| 		return true; | |||
| 	} | |||
| 
 | |||
| 	std::string toFormulaString() const { | |||
| 		std::string desc = "filter("; | |||
| 		return desc; | |||
| 	} | |||
| 
 | |||
| 	std::string toString() const { | |||
| 		std::string desc = "Filter: "; | |||
| 		desc += "\nActions:"; | |||
| 		for(auto action : actions) { | |||
| 			desc += "\n\t" + action.toString(); | |||
| 		} | |||
| 		desc += "\nFormula:\n\t" + child->toString(); | |||
| 		return desc; | |||
| 	} | |||
| 
 | |||
| 	void setChild(AbstractCslFormula* child) { | |||
| 		this->child = child; | |||
| 	} | |||
| 
 | |||
| 	AbstractFormula* getChild() const { | |||
| 		return child; | |||
| 	} | |||
| 
 | |||
| private: | |||
| 
 | |||
| 	BitVector evaluate(AbstractModelChecker const & modelchecker, AbstractStateFormula<T>* formula) const { | |||
| 		// First, get the model checking result. | |||
| 		BitVector result = modelchecker.checkMinMaxOperator(formula); | |||
| 
 | |||
| 		if(getActionCount() != 0 &&  dynamic_cast<MinMaxAction<T>*>(getAction(0)) != nullptr) { | |||
| 			// If there is an action specifying that min/max probabilities should be computed, call the appropriate method of the model checker. | |||
| 			result = modelchecker.checkMinMaxOperator(formula, static_cast<MinMaxAction<T>*>(getAction(0))->getMinimize()); | |||
| 		} else { | |||
| 			result = formula->check(modelchecker); | |||
| 		} | |||
| 
 | |||
| 
 | |||
| 		// Now apply all filter actions and return the result. | |||
| 		for(auto action : actions) { | |||
| 			result = action->evaluate(result); | |||
| 		} | |||
| 		return result; | |||
| 	} | |||
| 
 | |||
| 	std::vector<T> evaluate(AbstractModelChecker const & modelchecker, AbstractPathFormula<T>* formula) const { | |||
| 		// First, get the model checking result. | |||
| 		std::vector<T> result; | |||
| 
 | |||
| 		if(getActionCount() != 0 &&  dynamic_cast<MinMaxAction<T>*>(getAction(0)) != nullptr) { | |||
| 			// If there is an action specifying that min/max probabilities should be computed, call the appropriate method of the model checker. | |||
| 			result = modelchecker.checkMinMaxOperator(formula, static_cast<MinMaxAction<T>*>(getAction(0))->getMinimize()); | |||
| 		} else { | |||
| 			result = formula->check(modelchecker, false); | |||
| 		} | |||
| 
 | |||
| 		// Now apply all filter actions and return the result. | |||
| 		for(auto action : actions) { | |||
| 			result = action->evaluate(result); | |||
| 		} | |||
| 		return result; | |||
| 	} | |||
| 
 | |||
| 	AbstractCslFormula* child; | |||
| }; | |||
| 
 | |||
| } //namespace csl | |||
| } //namespace property | |||
| } //namespace storm | |||
| 
 | |||
| #endif /* STORM_FORMULA_CSL_CSLFILTER_H_ */ | |||
| @ -0,0 +1,138 @@ | |||
| /* | |||
|  * LtlFilter.h | |||
|  * | |||
|  *  Created on: May 7, 2014 | |||
|  *      Author: Manuel Sascha Weiand | |||
|  */ | |||
| 
 | |||
| #ifndef STORM_FORMULA_LTL_LTLFILTER_H_ | |||
| #define STORM_FORMULA_LTL_LTLFILTER_H_ | |||
| 
 | |||
| namespace storm { | |||
| namespace property { | |||
| namespace ltl { | |||
| 
 | |||
| template <class T> | |||
| class LtlFilter : storm::property::AbstractFilter<T> { | |||
| 
 | |||
| public: | |||
| 
 | |||
| 	LtlFilter() : child(nullptr) { | |||
| 		// Intentionally left empty. | |||
| 	} | |||
| 
 | |||
| 	LtlFilter(AbstractLtlFormula* child) : child(child) { | |||
| 		// Intentionally left empty. | |||
| 	} | |||
| 
 | |||
| 	LtlFilter(AbstractLtlFormula* child, action::Action<T>* action) : child(child) { | |||
| 		actions.push_back(action); | |||
| 	} | |||
| 
 | |||
| 	LtlFilter(AbstractLtlFormula* child, std::vector<action::Action<T>*> actions) : child(child), actions(actions) { | |||
| 		// Intentionally left empty. | |||
| 	} | |||
| 
 | |||
| 	virtual ~LtlFilter() { | |||
| 		actions.clear(); | |||
| 		delete child; | |||
| 	} | |||
| 
 | |||
| 
 | |||
| 	/*!Description copied from the MC. | |||
| 	 * Checks the given state formula on the model and prints the result (true/false) for all initial states, i.e. | |||
| 	 * states that carry the atomic proposition "init". | |||
| 	 * | |||
| 	 * @param stateFormula The formula to be checked. | |||
| 	 */ | |||
| 	void check(AbstractModelChecker const & modelchecker) const { | |||
| 
 | |||
| 		// Write out the formula to be checked. | |||
| 		std::cout << std::endl; | |||
| 		LOG4CPLUS_INFO(logger, "Model checking formula\t" << this->toFormulaString()); | |||
| 		std::cout << "Model checking formula:\t" << this->toFormulaString() << std::endl; | |||
| 
 | |||
| 
 | |||
| 		// Check the formula and apply the filter actions. | |||
| 		storm::storage::BitVector result; | |||
| 
 | |||
| 		try { | |||
| 			result = evaluate(modelchecker, child); | |||
| 		} catch (std::exception& e) { | |||
| 			std::cout << "Error during computation: " << e.what() << "Skipping property." << std::endl; | |||
| 			LOG4CPLUS_ERROR(logger, "Error during computation: " << e.what() << "Skipping property."); | |||
| 			std::cout << std::endl << "-------------------------------------------" << std::endl; | |||
| 
 | |||
| 			return; | |||
| 		} | |||
| 
 | |||
| 		// Now write out the result. | |||
| 
 | |||
| 		if(actions.empty()) { | |||
| 
 | |||
| 			// There is no filter action given. So provide legacy support: | |||
| 			// Return the results for all states labeled with "init". | |||
| 			LOG4CPLUS_INFO(logger, "Result for initial states:"); | |||
| 			std::cout << "Result for initial states:" << std::endl; | |||
| 			for (auto initialState : modelchecker.getModel<storm::models::AbstractModel<T>>().getInitialStates()) { | |||
| 				LOG4CPLUS_INFO(logger, "\t" << initialState << ": " << (result.get(initialState) ? "satisfied" : "not satisfied")); | |||
| 				std::cout << "\t" << initialState << ": " << result.get(initialState) << std::endl; | |||
| 			} | |||
| 		} | |||
| 
 | |||
| 		std::cout << std::endl << "-------------------------------------------" << std::endl; | |||
| 	} | |||
| 
 | |||
| 	bool validate() const { | |||
| 		// Test whether the stored filter actions are consistent in relation to themselves and to the ingoing modelchecking result. | |||
| 
 | |||
| 		//TODO: Actual validation. | |||
| 
 | |||
| 		return true; | |||
| 	} | |||
| 
 | |||
| 	std::string toFormulaString() const { | |||
| 		std::string desc = "filter("; | |||
| 		return desc; | |||
| 	} | |||
| 
 | |||
| 	std::string toString() const { | |||
| 		std::string desc = "Filter: "; | |||
| 		desc += "\nActions:"; | |||
| 		for(auto action : actions) { | |||
| 			desc += "\n\t" + action.toString(); | |||
| 		} | |||
| 		desc += "\nFormula:\n\t" + child->toString(); | |||
| 		return desc; | |||
| 	} | |||
| 
 | |||
| 	void setChild(AbstractLtlFormula* child) { | |||
| 		this->child = child; | |||
| 	} | |||
| 
 | |||
| 	AbstractFormula* getChild() const { | |||
| 		return child; | |||
| 	} | |||
| 
 | |||
| private: | |||
| 
 | |||
| 	storm::storage::BitVector evaluate(AbstractModelChecker const & modelchecker, AbstractLtlFormula<T>* formula) const { | |||
| 		// First, get the model checking result. | |||
| 		storm::storage::BitVector result = formula->check(modelchecker); | |||
| 
 | |||
| 		// Now apply all filter actions and return the result. | |||
| 		for(auto action : actions) { | |||
| 			result = action->evaluate(result); | |||
| 		} | |||
| 		return result; | |||
| 	} | |||
| 
 | |||
| 	AbstractLtlFormula* child; | |||
| }; | |||
| 
 | |||
| 
 | |||
| } //namespace ltl | |||
| } //namespace property | |||
| } //namespace storm | |||
| 
 | |||
| #endif /* STORM_FORMULA_LTL_LTLFILTER_H_ */ | |||
						Write
						Preview
					
					
					Loading…
					
					Cancel
						Save
					
		Reference in new issue