private double CalculateProbabilityToReachStateFormula(Formula psi)
        {
            // calculate P [true U psi]
            var psiEvaluator = MarkovChain.CreateFormulaEvaluator(psi);

            var precalculatedStates = CreateEmptyPrecalculatedStatesArray();

            CalculateSatisfiedStates(precalculatedStates, psiEvaluator);
            //CalculateExcludedStates(precalculatedStates);  // change for \phi Until \psi

            // calculate probabilityExactlyZero (prob0)
            ProbabilityExactlyZero(precalculatedStates);

            // calculate probabilityExactlyOne (prob1)
            ProbabilityExactlyOne(precalculatedStates);

            //TODO: Do not calculate exact state probabilities, when _every_ initial state>0 is either in probabilityExactlyZero or in probabilityExactlyOne

            var derivedMatrix = CreateDerivedMatrix(precalculatedStates);
            var derivedVector = CreateDerivedVector(precalculatedStates, PrecalculatedState.ExaclyOneForFinally);

            var resultVector     = GaussSeidel(derivedMatrix, derivedVector, 50);
            var finalProbability = CalculateFinalProbability(resultVector);

            return(finalProbability);
        }
        private double CalculateProbabilityToReachStateFormula(Formula psi)
        {
            // calculate P [true U psi]
            var psiEvaluator            = MarkovChain.CreateFormulaEvaluator(psi);
            var directlySatisfiedStates = CalculateSatisfiedStates(psiEvaluator);
            var excludedStates          = new Dictionary <long, bool>();   // change for \phi Until \psi. For classical "Finally", no states are excluded

            // calculate probabilityExactlyZero (prob0)
            var probabilityExactlyZero = ProbabilityExactlyZero(directlySatisfiedStates, excludedStates);

            // calculate probabilityExactlyOne (prob1)
            var probabilityExactlyOne = ProbabilityExactlyOne(directlySatisfiedStates, excludedStates, probabilityExactlyZero);

            //TODO: Do not calculate exact state probabilities, when _every_ initial state>0 is either in probabilityExactlyZero or in probabilityExactlyOne

            var derivedMatrix = CreateDerivedMatrix(probabilityExactlyOne, probabilityExactlyZero);
            var derivedVector = CreateDerivedVector(probabilityExactlyOne);

            var resultVector     = GaussSeidel(derivedMatrix, derivedVector, 50);
            var finalProbability = CalculateFinalProbability(resultVector);

            return(finalProbability);
        }
        private double CalculateProbabilityToReachStateFormulaInBoundedSteps(Formula psi, Formula phi, int steps)
        {
            // Pr[phi U psi]
            // calculate P [true U<=steps psi]

            var stopwatch = new Stopwatch();

            stopwatch.Start();

            var psiEvaluator = MarkovChain.CreateFormulaEvaluator(psi);
            var stateCount   = MarkovChain.States;

            var directlySatisfiedStates = CalculateSatisfiedStates(psiEvaluator);
            Dictionary <long, bool> excludedStates;

            if (phi == null)
            {
                excludedStates = new Dictionary <long, bool>();
            }
            else
            {
                // excludedStates = Sat(\phi) \Cup Sat(psi)
                var phiEvaluator   = MarkovChain.CreateFormulaEvaluator(phi);
                var phiOrPsiStates = CalculateSatisfiedStates(phiEvaluator);
                foreach (var directlySatisfiedState in directlySatisfiedStates)
                {
                    phiOrPsiStates[directlySatisfiedState.Key] = true;
                }
                excludedStates = CreateComplement(phiOrPsiStates);
            }

            var enumerator = MarkovChain.GetEnumerator();

            var xold  = new double[stateCount];
            var xnew  = CreateDerivedVector(directlySatisfiedStates);
            var loops = 0;

            while (loops < steps)
            {
                // switch xold and xnew
                var xtemp = xold;
                xold = xnew;
                xnew = xtemp;
                loops++;
                for (var i = 0; i < stateCount; i++)
                {
                    if (directlySatisfiedStates.ContainsKey(i))
                    {
                        //we could remove this line, because already set by CreateDerivedVector and never changed when we initialize xold with CreateDerivedVector(directlySatisfiedStates)
                        xnew[i] = 1.0;
                    }
                    else if (excludedStates.ContainsKey(i))
                    {
                        //we could remove this line, because already set by CreateDerivedVector and never changed when we initialize xold with CreateDerivedVector(directlySatisfiedStates)
                        xnew[i] = 0.0;
                    }
                    else
                    {
                        enumerator.SelectSourceState(i);
                        var sum = 0.0;
                        while (enumerator.MoveNextTransition())
                        {
                            var entry = enumerator.CurrentTransition;
                            sum += entry.Value * xold[entry.Column];
                        }
                        xnew[i] = sum;
                    }
                }

                if (loops % 10 == 0)
                {
                    stopwatch.Stop();
                    var currentProbability = CalculateFinalProbability(xnew);
                    _output?.WriteLine($"{loops} Bounded Until iterations in {stopwatch.Elapsed}. Current probability={currentProbability.ToString(CultureInfo.InvariantCulture)}");
                    stopwatch.Start();
                }
            }

            var finalProbability = CalculateFinalProbability(xnew);

            stopwatch.Stop();
            return(finalProbability);
        }
        private double CalculateUnboundUntil(Formula psi, Formula phi, int iterationsLeft)
        {
            // On algorithmic verification methods for probabilistic systems (1998) by Christel Baier
            // Theorem 3.1.6 (page 36)
            // http://wwwneu.inf.tu-dresden.de/content/institutes/thi/algi/publikationen/texte/15_98.pdf

            // Pr[phi U psi]
            // calculate P [true U<=steps psi]

            var stopwatch = new Stopwatch();

            stopwatch.Start();

            var psiEvaluator = MarkovChain.CreateFormulaEvaluator(psi);
            var stateCount   = MarkovChain.States;

            var fixPointReached = iterationsLeft <= 0;

            var directlySatisfiedStates = CalculateSatisfiedStates(psiEvaluator);
            Dictionary <long, bool> excludedStates;

            if (phi == null)
            {
                excludedStates = new Dictionary <long, bool>();
            }
            else
            {
                // excludedStates = Sat(\phi) \Cup Sat(psi)
                var phiEvaluator   = MarkovChain.CreateFormulaEvaluator(phi);
                var phiOrPsiStates = CalculateSatisfiedStates(phiEvaluator);
                foreach (var directlySatisfiedState in directlySatisfiedStates)
                {
                    phiOrPsiStates[directlySatisfiedState.Key] = true;
                }
                excludedStates = CreateComplement(phiOrPsiStates);
            }

            // calculate probabilityExactlyZero (prob0)
            var probabilityExactlyZero = ProbabilityExactlyZero(directlySatisfiedStates, excludedStates);

            // calculate probabilityExactlyOne (prob1)
            var probabilityExactlyOne = ProbabilityExactlyOne(directlySatisfiedStates, excludedStates, probabilityExactlyZero);


            var enumerator = MarkovChain.GetEnumerator();

            var xold  = new double[stateCount];
            var xnew  = CreateDerivedVector(probabilityExactlyOne);
            var loops = 0;

            while (!fixPointReached)
            {
                // switch xold and xnew
                var xtemp = xold;
                xold = xnew;
                xnew = xtemp;
                iterationsLeft--;
                loops++;
                for (var i = 0; i < stateCount; i++)
                {
                    if (probabilityExactlyOne.ContainsKey(i))
                    {
                        //we could remove this line, because already set by CreateDerivedVector and never changed when we initialize xold with CreateDerivedVector(directlySatisfiedStates)
                        xnew[i] = 1.0;
                    }
                    else if (probabilityExactlyZero.ContainsKey(i))
                    {
                        //we could remove this line, because already set by CreateDerivedVector and never changed when we initialize xold with CreateDerivedVector(directlySatisfiedStates)
                        xnew[i] = 0.0;
                    }
                    else
                    {
                        enumerator.SelectSourceState(i);
                        var sum = 0.0;
                        while (enumerator.MoveNextTransition())
                        {
                            var entry = enumerator.CurrentTransition;
                            sum += entry.Value * xold[entry.Column];
                        }
                        xnew[i] = sum;
                    }
                }

                if (loops % 10 == 0)
                {
                    stopwatch.Stop();
                    var currentProbability = CalculateFinalProbability(xnew);
                    _output?.WriteLine($"{loops} Fixpoint Until iterations in {stopwatch.Elapsed}. Current probability={currentProbability.ToString(CultureInfo.InvariantCulture)}");
                    stopwatch.Start();
                }
                if (iterationsLeft <= 0)
                {
                    fixPointReached = true;
                }
            }

            var finalProbability = CalculateFinalProbability(xnew);

            stopwatch.Stop();
            return(finalProbability);
        }
        private double CalculateProbabilityToReachStateFormulaInBoundedSteps(Formula psi, int steps)
        {
            // calculate P [true U<=steps psi]


            var stopwatch = new Stopwatch();

            stopwatch.Start();

            var psiEvaluator = MarkovChain.CreateFormulaEvaluator(psi);
            var stateCount   = MarkovChain.States;

            var precalculatedStates = CreateEmptyPrecalculatedStatesArray();

            CalculateSatisfiedStates(precalculatedStates, psiEvaluator);
            //CalculateExcludedStates(precalculatedStates);  // change for \phi Until \psi

            var enumerator = MarkovChain.GetEnumerator();

            var xold  = new double[stateCount];
            var xnew  = CreateDerivedVector(precalculatedStates, PrecalculatedState.Satisfied);
            var loops = 0;

            while (loops < steps)
            {
                // switch xold and xnew
                var xtemp = xold;
                xold = xnew;
                xnew = xtemp;
                loops++;
                for (var i = 0; i < stateCount; i++)
                {
                    if (precalculatedStates[i].HasFlag(PrecalculatedState.Satisfied))
                    {
                        //we could remove this line, because already set by CreateDerivedVector and never changed when we initialize xold with CreateDerivedVector(directlySatisfiedStates)
                        xnew[i] = 1.0;
                    }
                    else if (precalculatedStates[i].HasFlag(PrecalculatedState.Excluded))
                    {
                        //we could remove this line, because already set by CreateDerivedVector and never changed when we initialize xold with CreateDerivedVector(directlySatisfiedStates)
                        xnew[i] = 0.0;
                    }
                    else
                    {
                        enumerator.SelectSourceState(i);
                        var sum = 0.0;
                        while (enumerator.MoveNextTransition())
                        {
                            var entry = enumerator.CurrentTransition;
                            sum += entry.Value * xold[entry.Column];
                        }
                        xnew[i] = sum;
                    }
                }

                if (loops % 10 == 0)
                {
                    stopwatch.Stop();
                    var currentProbability = CalculateFinalProbability(xnew);
                    _output?.WriteLine($"{loops} Bounded Until iterations in {stopwatch.Elapsed}. Current probability={currentProbability.ToString(CultureInfo.InvariantCulture)}");
                    stopwatch.Start();
                }
            }

            var finalProbability = CalculateFinalProbability(xnew);

            stopwatch.Stop();
            return(finalProbability);
        }