@ -9,121 +9,129 @@ 
			
		
	
		
			
				
					# include  <storm/logic/Formula.h> 
  
			
		
	
		
			
				
					# include  <storm/modelchecker/propositional/SparsePropositionalModelChecker.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/NotSupportedException.h" 
  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					# include  <set> 
  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					# include  "storm/storage/BitVector.h" 
  
			
		
	
		
			
				
					# include  "storm/utility/macros.h" 
  
			
		
	
		
			
				
					
 
			
		
	
		
			
				
					namespace  storm  {  
			
		
	
		
			
				
					    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>>;
  
			
		
	
		
			
				
					    }  
			
		
	
		
			
				
					}