protected void OnInitialStateAdded(object sender, IEpaBuilder epaBuilder) { generatedEpa = epaBuilder.Build(); var stateAddedEventArg = new StateAddedEventArgs(epaBuilder.Type, epaBuilder, generatedEpa.Initial); StateAdded(sender, stateAddedEventArg); }
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); }
public Epa Build() { return(epaBuilder.Build()); }
/// <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()); }