Example #1
0
        protected void OnInitialStateAdded(object sender, IEpaBuilder epaBuilder)
        {
            generatedEpa = epaBuilder.Build();
            var stateAddedEventArg = new StateAddedEventArgs(epaBuilder.Type, epaBuilder, generatedEpa.Initial);

            StateAdded(sender, stateAddedEventArg);
        }
Example #2
0
        protected async Task <TypeAnalysisResult> GenerateEpaAndStatistics(ISet <Action> constructors, ISet <Action> actions, IEpaBuilder epaBuilder)
        {
            var analysisTimer = Stopwatch.StartNew();

            await Task.Run(() => GenerateEpa(constructors, actions, epaBuilder));

            analysisTimer.Stop();

            var analysisResult = new TypeAnalysisResult(epaBuilder.Build(), analysisTimer.Elapsed, analyzerFactory.GeneratedQueriesCount,
                                                        analyzerFactory.UnprovenQueriesCount);

            return(analysisResult);
        }
Example #3
0
 public Epa Build()
 {
     return(epaBuilder.Build());
 }
Example #4
0
        /// <summary>
        ///     Method to create an EPA of a particular type considering only the subset 'methods'
        /// </summary>
        /// <see cref="http://publicaciones.dc.uba.ar/Publications/2011/DBGU11/paper-icse-2011.pdf">Algorithm 1</see>
        protected Epa GenerateEpa(ISet <Action> constructors, ISet <Action> actions, IEpaBuilder epaBuilder)
        {
            Contract.Requires(constructors != null);
            Contract.Requires(actions != null);
            Contract.Requires(epaBuilder != null);

            var initialState  = new State(constructors, new HashSet <Action>());
            var statesToVisit = new Queue <State>();
            var visitedStates = new HashSet <State>();

            statesToVisit.Enqueue(initialState);

            while (statesToVisit.Count > 0)
            {
                var source = statesToVisit.Dequeue();
                visitedStates.Add(source);

                try
                {
                    // Change ParallelOptions.MaxDegreeOfParallelism to 1 to make the loop sequential.
                    Parallel.ForEach(source.EnabledActions, new ParallelOptions(), action =>
                    {
                        var analyzer = analyzerFactory.CreateAnalyzer();

                        // Which actions are enabled or disabled if 'action' is called from 'source'?
                        var actionsResult = analyzer.AnalyzeActions(source, action, actions);
                        if (actionsResult.EnabledActions.Count.Equals(actions.Count) && actionsResult.DisabledActions.Count.Equals(actions.Count))
                        {
                            Logger.Log(LogLevel.Warn,
                                       "Suspicious state! Only a state with a unsatisfiable invariant can lead to every action being enabled and disabled at the same time. It can also mean a bug in our code.");
                            return;
                        }

                        Contract.Assert(!actionsResult.EnabledActions.Intersect(actionsResult.DisabledActions).Any(), "Results should be consistent");
                        if (!actionsResult.EnabledActions.Any() && !actionsResult.DisabledActions.Any())
                        {
                            Logger.Log(LogLevel.Warn, "State explosion!");
                        }

                        var possibleTargets = GeneratePossibleStates(actions, actionsResult);

                        if (cutter > 0 && possibleTargets.Count > cutter)
                        {
                            throw new Exception("Number of states too big.");
                        }

                        Contract.Assert(possibleTargets.Any(), "There is always at least one target to reach");

                        // Which states are reachable from the current state (aka source) using 'action'?
                        var transitionsResults = analyzer.AnalyzeTransitions(source, action, possibleTargets);

                        if (!transitionsResults.Any())
                        {
                            Logger.Log(LogLevel.Warn, "No states are reachable.");
                        }

                        foreach (var transition in transitionsResults)
                        {
                            var target = transition.TargetState;
                            // Do I have to add a new state to the EPA?
                            if (!visitedStates.Contains(target) && !statesToVisit.Contains(target))
                            {
                                statesToVisit.Enqueue(target);
                            }
                            epaBuilder.Add(transition);
                        }

                        analyzerFactory.GeneratedQueriesCount += analyzer.GeneratedQueriesCount();
                        analyzerFactory.UnprovenQueriesCount  += analyzer.UnprovenQueriesCount();
                    });
                }
                catch (AggregateException e)
                {
                    foreach (var ex in e.InnerExceptions)
                    {
                        if (ex.GetType() == typeof(OperationCanceledException))
                        {
                            throw ex;
                        }
                    }
                }
            }

            return(epaBuilder.Build());
        }