private PrecalculatedTransitionTarget[] CreateSimplePrecalculatedTransitionTargets(Formula phi, Formula psi)
        {
            var psiEvaluator = LabeledMarkovChain.CreateFormulaEvaluator(psi);

            var precalculatedTransitionTargets = CreateEmptyPrecalculatedTransitionTargetArray();

            CalculateSatisfiedTargets(precalculatedTransitionTargets, psiEvaluator);
            if (phi != null)
            {
                // excludedStates = Sat(\phi) \Cup Sat(psi)
                var phiEvaluator = LabeledMarkovChain.CreateFormulaEvaluator(phi);
                Func <long, bool> calculateExcludedStates = target =>
                {
                    if (precalculatedTransitionTargets[target] == PrecalculatedTransitionTarget.SatisfiedDirect)
                    {
                        return(false);                        //satisfied states are never excluded
                    }
                    if (!phiEvaluator(target))
                    {
                        return(true);                        //exclude state if it does not satisfy phi
                    }
                    return(false);
                };
                CalculateExcludedTargets(precalculatedTransitionTargets, calculateExcludedStates);
            }
            return(precalculatedTransitionTargets);
        }
 // Note: Should be used with using(var modelchecker = new ...)
 public BuiltinLtmcModelChecker(LabeledTransitionMarkovChain markovChain, TextWriter output = null)
     : base(markovChain, output)
 {
     Requires.That(true, "Need CompactStateStorage to use this model checker");
     LabeledMarkovChain.AssertIsDense();
     output.WriteLine("Initializing Built-in Ltmc Model checker");
 }
 private void CalculateUnderlyingDigraph()
 {
     // We use the underlying digraph to interfere the transitionTargets with the final probability
     // of 0 or 1.
     // I think, the data from the graph is also valid for the states. So, if a state-node
     // is in Prob0 or Prob1, then we can also assume that the state has always probability 0 or 1,
     // respectively. One further check can could be introduced. When we know that the probability
     // of a state is 0 or 1, then we do not have to check the outgoing transitionTargets anymore.
     if (_underlyingDigraph != null)
     {
         return;
     }
     _output.WriteLine("Creating underlying digraph");
     _underlyingDigraph = LabeledMarkovChain.CreateUnderlyingDigraph();
     _output.WriteLine("Finished creating underlying digraph");
 }
        private double CalculateFinalUnboundedProbability(double[] initialStateProbabilities, PrecalculatedTransitionTarget[] precalculatedTransitionTargets)
        {
            var finalProbability = 0.0;

            var enumerator = LabeledMarkovChain.GetInitialDistributionEnumerator();

            while (enumerator.MoveNext())
            {
                var transitionTarget = enumerator.CurrentIndex;
                if (precalculatedTransitionTargets[transitionTarget].HasFlag(PrecalculatedTransitionTarget.SatisfiedFinally))
                {
                    finalProbability += enumerator.CurrentProbability;
                }
                else if (precalculatedTransitionTargets[transitionTarget].HasFlag(PrecalculatedTransitionTarget.ExcludedFinally))
                {
                }
                else
                {
                    finalProbability += enumerator.CurrentProbability * initialStateProbabilities[enumerator.CurrentTargetState];
                }
            }
            return(finalProbability);
        }
        private double CalculateUnboundUntil(Formula phi, Formula psi, int iterationsLeft)
        {
            // Based on the iterative idea by:
            // 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 fixPointReached = iterationsLeft <= 0;

            var precalculatedTransitionTargets = CreateSimplePrecalculatedTransitionTargets(phi, psi);

            CalculateProb0TransitionTargets(precalculatedTransitionTargets);
            CalculateProb1TransitionTargets(precalculatedTransitionTargets);

            var stateCount = LabeledMarkovChain.SourceStates.Count;

            var xold  = new double[stateCount];
            var xnew  = new double[stateCount];
            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++)
                {
                    var enumerator = LabeledMarkovChain.GetTransitionEnumerator(i);
                    var sum        = 0.0;

                    while (enumerator.MoveNext())
                    {
                        var transitionTarget = enumerator.CurrentIndex;
                        if (precalculatedTransitionTargets[transitionTarget].HasFlag(PrecalculatedTransitionTarget.SatisfiedFinally))
                        {
                            sum += enumerator.CurrentProbability;
                        }
                        else if (precalculatedTransitionTargets[transitionTarget].HasFlag(PrecalculatedTransitionTarget.ExcludedFinally))
                        {
                        }
                        else
                        {
                            sum += enumerator.CurrentProbability * xold[enumerator.CurrentTargetState];
                        }
                    }
                    xnew[i] = sum;
                }

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

            var finalProbability = CalculateFinalUnboundedProbability(xnew, precalculatedTransitionTargets);

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

            var stopwatch = new Stopwatch();

            stopwatch.Start();

            var precalculatedTransitionTargets = CreateSimplePrecalculatedTransitionTargets(phi, psi);

            var stateCount = LabeledMarkovChain.SourceStates.Count;

            var xold  = new double[stateCount];
            var xnew  = new double[stateCount];
            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++)
                {
                    var enumerator = LabeledMarkovChain.GetTransitionEnumerator(i);
                    var sum        = 0.0;

                    while (enumerator.MoveNext())
                    {
                        var transitionTarget = enumerator.CurrentIndex;
                        if (precalculatedTransitionTargets[transitionTarget].HasFlag(PrecalculatedTransitionTarget.SatisfiedDirect))
                        {
                            sum += enumerator.CurrentProbability;
                        }
                        else if (precalculatedTransitionTargets[transitionTarget].HasFlag(PrecalculatedTransitionTarget.ExcludedDirect))
                        {
                        }
                        else
                        {
                            sum += enumerator.CurrentProbability * xold[enumerator.CurrentTargetState];
                        }
                    }
                    xnew[i] = sum;
                }

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

            var finalProbability = CalculateFinalBoundedProbability(xnew, precalculatedTransitionTargets);

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