@ -9,121 +9,129 @@ 
		
	
		
			
				# include  <storm/logic/Formula.h> 
 # include  <storm/logic/Formula.h> 
  
		
	
		
			
				# include  <storm/modelchecker/propositional/SparsePropositionalModelChecker.h> 
 # include  <storm/modelchecker/propositional/SparsePropositionalModelChecker.h> 
  
		
	
		
			
				# include  "storm/models/sparse/Model.h" 
 # include  "storm/models/sparse/Model.h" 
  
		
	
		
			
				# include  "storm/modelchecker/results/CheckResult.h" 
  
		
	
		
			
				# include  "storm/modelchecker/results/ExplicitQualitativeCheckResult.h" 
  
		
	
		
			
				
 
		
	
		
			
				
 
		
	
		
			
				# include  "storm/exceptions/NotImplementedException.h" 
 # include  "storm/exceptions/NotImplementedException.h" 
  
		
	
		
			
				# include  "storm/exceptions/NotSupportedException.h" 
 # include  "storm/exceptions/NotSupportedException.h" 
  
		
	
		
			
				
 
		
	
		
			
				# include  <set> 
 # include  <set> 
  
		
	
		
			
				
 
		
	
		
			
				# include  "storm/storage/BitVector.h" 
  
		
	
		
			
				# include  "storm/utility/macros.h" 
  
		
	
		
			
				
 
		
	
		
			
				namespace  storm  { namespace  storm  {  
		
	
		
			
				    namespace  analysis  {     namespace  analysis  {  
		
	
		
			
				
 
		
	
		
			
				        template   < typename  Value Type>  
		
	
		
			
				        LatticeExtender < Value Type> : : LatticeExtender ( ) { //std::shared_ptr<storm::models::sparse::Dtmc<ValueType>> model) {
  
		
	
		
			
				            //TODO 
  
		
	
		
			
				        template < typename  SparseModel Type>  
		
	
		
			
				        LatticeExtender < SparseModel Type> : : LatticeExtender ( std : : shared_ptr < SparseModelType >  model )  :  model ( model )  {  
		
	
		
			
				            // intentionally left empty 
  
		
	
		
			
				        }         }  
		
	
		
			
				
 
		
	
		
			
				//        template <typename ValueType>
  
		
	
		
			
				//        storm::analysis::Lattice* LatticeExtender<ValueType>::toLattice(std::vector<std::shared_ptr<storm::logic::Formula const>> formulas) {
  
		
	
		
			
				//            STORM_LOG_THROW((++formulas.begin()) == formulas.end(), storm::exceptions::NotSupportedException, "Only one formula allowed for monotonicity analysis");
  
		
	
		
			
				//            STORM_LOG_THROW((*(formulas[0])).isProbabilityOperatorFormula()
  
		
	
		
			
				//                            && ((*(formulas[0])).asProbabilityOperatorFormula().getSubformula().isUntilFormula()
  
		
	
		
			
				//                                || (*(formulas[0])).asProbabilityOperatorFormula().getSubformula().isEventuallyFormula()), storm::exceptions::NotSupportedException, "Expecting until formula");
  
		
	
		
			
				//
  
		
	
		
			
				//            uint_fast64_t numberOfStates = this->model.getNumberOfStates();
  
		
	
		
			
				//
  
		
	
		
			
				//            storm::modelchecker::SparsePropositionalModelChecker<storm::models::sparse::Model<ValueType>> propositionalChecker(this->model);
  
		
	
		
			
				//            storm::storage::BitVector phiStates;
  
		
	
		
			
				//            storm::storage::BitVector psiStates;
  
		
	
		
			
				//            if ((*(formulas[0])).asProbabilityOperatorFormula().getSubformula().isUntilFormula()) {
  
		
	
		
			
				//                phiStates = propositionalChecker.check((*(formulas[0])).asProbabilityOperatorFormula().getSubformula().asUntilFormula().getLeftSubformula())->asExplicitQualitativeCheckResult().getTruthValuesVector();
  
		
	
		
			
				//                psiStates = propositionalChecker.check((*(formulas[0])).asProbabilityOperatorFormula().getSubformula().asUntilFormula().getRightSubformula())->asExplicitQualitativeCheckResult().getTruthValuesVector();
  
		
	
		
			
				//            } else {
  
		
	
		
			
				//                phiStates = storm::storage::BitVector(numberOfStates, true);
  
		
	
		
			
				//                psiStates = propositionalChecker.check((*(formulas[0])).asProbabilityOperatorFormula().getSubformula().asEventuallyFormula().getSubformula())->asExplicitQualitativeCheckResult().getTruthValuesVector();
  
		
	
		
			
				//            }
  
		
	
		
			
				//
  
		
	
		
			
				//            // Get the maybeStates
  
		
	
		
			
				//            std::pair<storm::storage::BitVector, storm::storage::BitVector> statesWithProbability01 = storm::utility::graph::performProb01(this->model.getBackwardTransitions(), phiStates, psiStates);
  
		
	
		
			
				//            storm::storage::BitVector topStates = statesWithProbability01.second;
  
		
	
		
			
				//            storm::storage::BitVector bottomStates = statesWithProbability01.first;
  
		
	
		
			
				//
  
		
	
		
			
				//            STORM_LOG_THROW(topStates.begin() != topStates.end(), storm::exceptions::NotImplementedException, "Formula yields to no 1 states");
  
		
	
		
			
				//            STORM_LOG_THROW(bottomStates.begin() != bottomStates.end(), storm::exceptions::NotImplementedException, "Formula yields to no zero states");
  
		
	
		
			
				//
  
		
	
		
			
				//            // Transform to Lattice
  
		
	
		
			
				//            auto matrix = this->model.getTransitionMatrix();
  
		
	
		
			
				//
  
		
	
		
			
				//            for (uint_fast64_t i = 0; i < numberOfStates; ++i) {
  
		
	
		
			
				//                stateMap[i] = storm::storage::BitVector(numberOfStates, false);
  
		
	
		
			
				//
  
		
	
		
			
				//                auto row = matrix.getRow(i);
  
		
	
		
			
				//                for (auto rowItr = row.begin(); rowItr != row.end(); ++rowItr) {
  
		
	
		
			
				//                    stateMap[i].set(rowItr->getColumn(), true);
  
		
	
		
			
				//                }
  
		
	
		
			
				//                // TODO: allow more than 2 transitions? or fix this in preprocessing?
  
		
	
		
			
				//                STORM_LOG_THROW(stateMap[i].getNumberOfSetBits() <= 2, storm::exceptions::NotSupportedException, "Only two outgoing transitions per state allowed");
  
		
	
		
			
				//            }
  
		
	
		
			
				//
  
		
	
		
			
				//            // Create the Lattice
  
		
	
		
			
				//            storm::analysis::Lattice *lattice = new storm::analysis::Lattice(topStates, bottomStates, numberOfStates);
  
		
	
		
			
				//            return this->extendLattice(lattice, std::set<storm::expressions::Expression>({}));
  
		
	
		
			
				//        }
  
		
	
		
			
				//
  
		
	
		
			
				//        template <typename ValueType>
  
		
	
		
			
				//        storm::analysis::Lattice* LatticeExtender<ValueType>::extendLattice(storm::analysis::Lattice* lattice, std::set<storm::expressions::Expression> assumptions) {
  
		
	
		
			
				//            uint_fast64_t numberOfStates = this->model.getNumberOfStates();
  
		
	
		
			
				//
  
		
	
		
			
				//            storm::storage::BitVector oldStates(numberOfStates);
  
		
	
		
			
				//
  
		
	
		
			
				//            // Create a copy of the states already present in the lattice.
  
		
	
		
			
				//            storm::storage::BitVector seenStates = lattice->getAddedStates();
  
		
	
		
			
				//
  
		
	
		
			
				//            while (oldStates != seenStates) {
  
		
	
		
			
				//                // As long as new states are added to the lattice, continue.
  
		
	
		
			
				//                oldStates = storm::storage::BitVector(seenStates);
  
		
	
		
			
				//
  
		
	
		
			
				//                for (auto stateItr = stateMap.begin(); stateItr != stateMap.end(); ++stateItr) {
  
		
	
		
			
				//                    // Iterate over all states
  
		
	
		
			
				//                    auto stateNumber = stateItr->first;
  
		
	
		
			
				//                    storm::storage::BitVector successors = stateItr->second;
  
		
	
		
			
				//
  
		
	
		
			
				//                    // Check if current state has not been added yet, and all successors have
  
		
	
		
			
				//                    bool check = !seenStates[stateNumber];
  
		
	
		
			
				//                    for (auto succIndex = successors.getNextSetIndex(0); check && succIndex != numberOfStates; succIndex = successors.getNextSetIndex(++succIndex)) {
  
		
	
		
			
				//                        check &= seenStates[succIndex];
  
		
	
		
			
				//                    }
  
		
	
		
			
				//
  
		
	
		
			
				//                    if (check && successors.getNumberOfSetBits() == 1) {
  
		
	
		
			
				//                        // As there is only one successor the current state and its successor must be at the same nodes.
  
		
	
		
			
				//                        lattice->addToNode(stateNumber, lattice->getNode(successors.getNextSetIndex(0)));
  
		
	
		
			
				//                        seenStates.set(stateNumber);
  
		
	
		
			
				//                    } else if (check && successors.getNumberOfSetBits() > 1) {
  
		
	
		
			
				//                        // TODO: allow more than 2 transitions?
  
		
	
		
			
				//
  
		
	
		
			
				//                        // Otherwise, check how the two states compare, and add if the comparison is possible.
  
		
	
		
			
				//                        uint_fast64_t successor1 = successors.getNextSetIndex(0);
  
		
	
		
			
				//                        uint_fast64_t successor2 = successors.getNextSetIndex(successor1 + 1);
  
		
	
		
			
				//                        int compareResult = lattice->compare(successor1, successor2);
  
		
	
		
			
				//                        if (compareResult == 1) {
  
		
	
		
			
				//                            // successor 1 is closer to top than successor 2
  
		
	
		
			
				//                            lattice->addBetween(stateNumber, lattice->getNode(successor1),
  
		
	
		
			
				//                                                lattice->getNode(successor2));
  
		
	
		
			
				//                        } else if (compareResult == 2) {
  
		
	
		
			
				//                            // successor 2 is closer to top than successor 1
  
		
	
		
			
				//                            lattice->addBetween(stateNumber, lattice->getNode(successor2),
  
		
	
		
			
				//                                                lattice->getNode(successor1));
  
		
	
		
			
				//                        } else if (compareResult == 0) {
  
		
	
		
			
				//                            // the successors are at the same level
  
		
	
		
			
				//                            lattice->addToNode(stateNumber, lattice->getNode(successor1));
  
		
	
		
			
				//                        } else {
  
		
	
		
			
				//                            // TODO: create critical pair
  
		
	
		
			
				//                        }
  
		
	
		
			
				//                        seenStates.set(stateNumber);
  
		
	
		
			
				//                    }
  
		
	
		
			
				//                }
  
		
	
		
			
				//            }
  
		
	
		
			
				//            return lattice;
  
		
	
		
			
				//        }
  
		
	
		
			
				        template  < typename  SparseModelType >  
		
	
		
			
				        storm : : analysis : : Lattice *  LatticeExtender < SparseModelType > : : toLattice ( std : : vector < std : : shared_ptr < storm : : logic : : Formula  const > >  formulas )  {  
		
	
		
			
				            STORM_LOG_THROW ( ( + + formulas . begin ( ) )  = =  formulas . end ( ) ,  storm : : exceptions : : NotSupportedException ,  " Only one formula allowed for monotonicity analysis " ) ;  
		
	
		
			
				            STORM_LOG_THROW ( ( * ( formulas [ 0 ] ) ) . isProbabilityOperatorFormula ( )  
		
	
		
			
				                            & &  ( ( * ( formulas [ 0 ] ) ) . asProbabilityOperatorFormula ( ) . getSubformula ( ) . isUntilFormula ( )  
		
	
		
			
				                                | |  ( * ( formulas [ 0 ] ) ) . asProbabilityOperatorFormula ( ) . getSubformula ( ) . isEventuallyFormula ( ) ) ,  storm : : exceptions : : NotSupportedException ,  " Expecting until formula " ) ;  
		
	
		
			
				
 
		
	
		
			
				            uint_fast64_t  numberOfStates  =  this - > model . get ( ) - > getNumberOfStates ( ) ;  
		
	
		
			
				
 
		
	
		
			
				            storm : : modelchecker : : SparsePropositionalModelChecker < SparseModelType >  propositionalChecker ( * model ) ;  
		
	
		
			
				            storm : : storage : : BitVector  phiStates ;  
		
	
		
			
				            storm : : storage : : BitVector  psiStates ;  
		
	
		
			
				            if  ( ( * ( formulas [ 0 ] ) ) . asProbabilityOperatorFormula ( ) . getSubformula ( ) . isUntilFormula ( ) )  {  
		
	
		
			
				                phiStates  =  propositionalChecker . check ( ( * ( formulas [ 0 ] ) ) . asProbabilityOperatorFormula ( ) . getSubformula ( ) . asUntilFormula ( ) . getLeftSubformula ( ) ) - > asExplicitQualitativeCheckResult ( ) . getTruthValuesVector ( ) ;  
		
	
		
			
				                psiStates  =  propositionalChecker . check ( ( * ( formulas [ 0 ] ) ) . asProbabilityOperatorFormula ( ) . getSubformula ( ) . asUntilFormula ( ) . getRightSubformula ( ) ) - > asExplicitQualitativeCheckResult ( ) . getTruthValuesVector ( ) ;  
		
	
		
			
				            }  else  {  
		
	
		
			
				                phiStates  =  storm : : storage : : BitVector ( numberOfStates ,  true ) ;  
		
	
		
			
				                psiStates  =  propositionalChecker . check ( ( * ( formulas [ 0 ] ) ) . asProbabilityOperatorFormula ( ) . getSubformula ( ) . asEventuallyFormula ( ) . getSubformula ( ) ) - > asExplicitQualitativeCheckResult ( ) . getTruthValuesVector ( ) ;  
		
	
		
			
				            }  
		
	
		
			
				
 
		
	
		
			
				            // Get the maybeStates
  
		
	
		
			
				            std : : pair < storm : : storage : : BitVector ,  storm : : storage : : BitVector >  statesWithProbability01  =  storm : : utility : : graph : : performProb01 ( this - > model . get ( ) - > getBackwardTransitions ( ) ,  phiStates ,  psiStates ) ;  
		
	
		
			
				            storm : : storage : : BitVector  topStates  =  statesWithProbability01 . second ;  
		
	
		
			
				            storm : : storage : : BitVector  bottomStates  =  statesWithProbability01 . first ;  
		
	
		
			
				
 
		
	
		
			
				            STORM_LOG_THROW ( topStates . begin ( )  ! =  topStates . end ( ) ,  storm : : exceptions : : NotImplementedException ,  " Formula yields to no 1 states " ) ;  
		
	
		
			
				            STORM_LOG_THROW ( bottomStates . begin ( )  ! =  bottomStates . end ( ) ,  storm : : exceptions : : NotImplementedException ,  " Formula yields to no zero states " ) ;  
		
	
		
			
				
 
		
	
		
			
				            // Transform to Lattice
  
		
	
		
			
				            auto  matrix  =  this - > model . get ( ) - > getTransitionMatrix ( ) ;  
		
	
		
			
				
 
		
	
		
			
				            for  ( uint_fast64_t  i  =  0 ;  i  <  numberOfStates ;  + + i )  {  
		
	
		
			
				                stateMap [ i ]  =  storm : : storage : : BitVector ( numberOfStates ,  false ) ;  
		
	
		
			
				
 
		
	
		
			
				                auto  row  =  matrix . getRow ( i ) ;  
		
	
		
			
				                for  ( auto  rowItr  =  row . begin ( ) ;  rowItr  ! =  row . end ( ) ;  + + rowItr )  {  
		
	
		
			
				                    stateMap [ i ] . set ( rowItr - > getColumn ( ) ,  true ) ;  
		
	
		
			
				                }  
		
	
		
			
				                // TODO: allow more than 2 transitions? or fix this in preprocessing?
  
		
	
		
			
				                STORM_LOG_THROW ( stateMap [ i ] . getNumberOfSetBits ( )  < =  2 ,  storm : : exceptions : : NotSupportedException ,  " Only two outgoing transitions per state allowed " ) ;  
		
	
		
			
				            }  
		
	
		
			
				
 
		
	
		
			
				            // Create the Lattice
  
		
	
		
			
				            storm : : analysis : : Lattice  * lattice  =  new  storm : : analysis : : Lattice ( topStates ,  bottomStates ,  numberOfStates ) ;  
		
	
		
			
				            return  this - > extendLattice ( lattice ,  std : : set < storm : : expressions : : Expression > ( { } ) ) ;  
		
	
		
			
				        }  
		
	
		
			
				
 
		
	
		
			
				        template  < typename  SparseModelType >  
		
	
		
			
				        storm : : analysis : : Lattice *  LatticeExtender < SparseModelType > : : extendLattice ( storm : : analysis : : Lattice *  lattice ,  std : : set < storm : : expressions : : Expression >  assumptions )  {  
		
	
		
			
				            uint_fast64_t  numberOfStates  =  this - > model . get ( ) - > getNumberOfStates ( ) ;  
		
	
		
			
				
 
		
	
		
			
				            storm : : storage : : BitVector  oldStates ( numberOfStates ) ;  
		
	
		
			
				
 
		
	
		
			
				            // Create a copy of the states already present in the lattice.
  
		
	
		
			
				            storm : : storage : : BitVector  seenStates  =  ( lattice - > getAddedStates ( ) ) ;  
		
	
		
			
				
 
		
	
		
			
				            while  ( oldStates  ! =  seenStates )  {  
		
	
		
			
				                // As long as new states are added to the lattice, continue.
  
		
	
		
			
				                oldStates  =  storm : : storage : : BitVector ( seenStates ) ;  
		
	
		
			
				
 
		
	
		
			
				                for  ( auto  stateItr  =  stateMap . begin ( ) ;  stateItr  ! =  stateMap . end ( ) ;  + + stateItr )  {  
		
	
		
			
				                    // Iterate over all states
  
		
	
		
			
				                    auto  stateNumber  =  stateItr - > first ;  
		
	
		
			
				                    storm : : storage : : BitVector  successors  =  stateItr - > second ;  
		
	
		
			
				
 
		
	
		
			
				                    // Check if current state has not been added yet, and all successors have
  
		
	
		
			
				                    bool  check  =  ! seenStates [ stateNumber ] ;  
		
	
		
			
				                    for  ( auto  succIndex  =  successors . getNextSetIndex ( 0 ) ;  check  & &  succIndex  ! =  numberOfStates ;  succIndex  =  successors . getNextSetIndex ( + + succIndex ) )  {  
		
	
		
			
				                        check  & =  seenStates [ succIndex ] ;  
		
	
		
			
				                    }  
		
	
		
			
				
 
		
	
		
			
				                    if  ( check  & &  successors . getNumberOfSetBits ( )  = =  1 )  {  
		
	
		
			
				                        // As there is only one successor the current state and its successor must be at the same nodes.
  
		
	
		
			
				                        lattice - > addToNode ( stateNumber ,  lattice - > getNode ( successors . getNextSetIndex ( 0 ) ) ) ;  
		
	
		
			
				                        seenStates . set ( stateNumber ) ;  
		
	
		
			
				                    }  else  if  ( check  & &  successors . getNumberOfSetBits ( )  >  1 )  {  
		
	
		
			
				                        // TODO: allow more than 2 transitions?
  
		
	
		
			
				                        // Otherwise, check how the two states compare, and add if the comparison is possible.
  
		
	
		
			
				                        uint_fast64_t  successor1  =  successors . getNextSetIndex ( 0 ) ;  
		
	
		
			
				                        uint_fast64_t  successor2  =  successors . getNextSetIndex ( successor1  +  1 ) ;  
		
	
		
			
				                        int  compareResult  =  lattice - > compare ( successor1 ,  successor2 ) ;  
		
	
		
			
				                        if  ( compareResult  = =  1 )  {  
		
	
		
			
				                            // successor 1 is closer to top than successor 2
  
		
	
		
			
				                            lattice - > addBetween ( stateNumber ,  lattice - > getNode ( successor1 ) ,  
		
	
		
			
				                                                lattice - > getNode ( successor2 ) ) ;  
		
	
		
			
				                        }  else  if  ( compareResult  = =  2 )  {  
		
	
		
			
				                            // successor 2 is closer to top than successor 1
  
		
	
		
			
				                            lattice - > addBetween ( stateNumber ,  lattice - > getNode ( successor2 ) ,  
		
	
		
			
				                                                lattice - > getNode ( successor1 ) ) ;  
		
	
		
			
				                        }  else  if  ( compareResult  = =  0 )  {  
		
	
		
			
				                            // the successors are at the same level
  
		
	
		
			
				                            lattice - > addToNode ( stateNumber ,  lattice - > getNode ( successor1 ) ) ;  
		
	
		
			
				                        }  else  {  
		
	
		
			
				                            // TODO: create critical pair
  
		
	
		
			
				                        }  
		
	
		
			
				                        seenStates . set ( stateNumber ) ;  
		
	
		
			
				                    }  
		
	
		
			
				                }  
		
	
		
			
				            }  
		
	
		
			
				            return  lattice ;  
		
	
		
			
				        }  
		
	
		
			
				
 
		
	
		
			
				        template  class  LatticeExtender < storm : : models : : sparse : : Model < storm : : RationalFunction > > ;  
		
	
		
			
				//        template class LatticeExtender<storm::models::sparse::Mdp<storm::RationalFunction>>;
  
		
	
		
			
				    }     }  
		
	
		
			
				} }