/// <summary> /// Generates a <see cref="LabeledTransitionMarkovChain" /> for the model created by <paramref name="createModel" />. /// </summary> internal LabeledTransitionMarkovChain GenerateLtmc(AnalysisModelCreator createModel) { using (var modelTraverser = new ModelTraverser(createModel, Configuration, LabeledTransitionMarkovChain.TransitionSize, FormulaManager.NeedsStutteringState)) { _markovChain = new LabeledTransitionMarkovChain(modelTraverser.Context.ModelCapacity.NumberOfStates, modelTraverser.Context.ModelCapacity.NumberOfTransitions); _markovChain.StateFormulaLabels = FormulaManager.FinalStateFormulaLabels.ToArray(); if (FormulaManager.NeedsStutteringState) { _markovChain.CreateStutteringState(modelTraverser.Context.StutteringStateIndex); } modelTraverser.Context.TraversalParameters.TransitionModifiers.AddRange(FormulaManager.TransitionModifierGenerators); modelTraverser.Context.TraversalParameters.TransitionModifiers.Add(() => new ConsolidateTransitionsModifier()); modelTraverser.Context.TraversalParameters.BatchedTransitionActions.Add(() => new LabeledTransitionMarkovChain.LtmcBuilder(_markovChain)); modelTraverser.Context.Output.WriteLine($"Generating labeled transition markov chain."); modelTraverser.TraverseModelAndReport(); // StateStorage must be freed manually. Reason is that invariant checker does not free up the // space, because it might be necessary for other usages of the ModelTraversers (e.g. StateGraphGenerator // which keeps the States for the StateGraph) modelTraverser.Context.States.SafeDispose(); } if (Configuration.WriteGraphvizModels) { FormulaManager.PrintStateFormulas(FormulaManager.FinalStateFormulas, Configuration.DefaultTraceOutput); Configuration.DefaultTraceOutput.WriteLine("Ltmc Model"); _markovChain.ExportToGv(Configuration.DefaultTraceOutput); } return(_markovChain); }
/// <summary> /// Initializes a new instance. /// </summary> /// <param name="createModel">Creates the model that should be checked.</param> /// <param name="executableStateFormulas">The state formulas that can be evaluated over the generated state graph.</param> /// <param name="output">The callback that should be used to output messages.</param> /// <param name="configuration">The analysis configuration that should be used.</param> internal LtmcGenerator(AnalysisModelCreator <TExecutableModel> createModel, Formula terminateEarlyCondition, Formula[] executableStateFormulas, Action <string> output, AnalysisConfiguration configuration) : base(createModel, output, configuration, LabeledTransitionMarkovChain.TransitionSize) { _markovChain = new LabeledTransitionMarkovChain(Context.ModelCapacity.NumberOfStates, Context.ModelCapacity.NumberOfTransitions); _markovChain.StateFormulaLabels = executableStateFormulas.Select(stateFormula => stateFormula.Label).ToArray(); Context.TraversalParameters.BatchedTransitionActions.Add(() => new LabeledTransitionMarkovChain.LtmcBuilder <TExecutableModel>(_markovChain)); if (terminateEarlyCondition != null) { _markovChain.CreateStutteringState(Context.StutteringStateIndex); var terminalteEarlyFunc = StateFormulaSetEvaluatorCompilationVisitor.Compile(_markovChain.StateFormulaLabels, terminateEarlyCondition); Context.TraversalParameters.TransitionModifiers.Add(() => new EarlyTerminationModifier <TExecutableModel>(terminalteEarlyFunc)); } }