/// <summary> /// Identifies the variables from the counter example. /// </summary> /// <param name="error">The error.</param> private void IdentifyVariables(RepairableError error) { // Filter the variables based on source locations if (error is RaceError) { Regex regex = new Regex(@"^b\d+$"); Dictionary <string, bool> assignments = new Dictionary <string, bool>(); IEnumerable <Model.Boolean> elements = error.CounterExample.Model.Elements .Where(x => x is Model.Boolean).Select(x => x as Model.Boolean); foreach (Model.Boolean element in elements) { element.References.Select(x => x.Func).Where(x => regex.IsMatch(x.Name)) .Select(x => x.Name).ToList().ForEach(x => assignments.Add(x, element.Value)); } foreach (string key in this.assignments.Keys) { if (assignments.ContainsKey(key)) { if (assignments[key] != this.assignments[key]) { throw new RepairException("The model value doesn't match the assignment value!"); } } else { assignments.Add(key, this.assignments[key]); } } bool value = error is RaceError ? false : true; IEnumerable <string> names = assignments.Where(x => x.Value == value).Select(x => x.Key); IEnumerable <Barrier> barriers = ProgramMetadata.Barriers .Where(x => names.Contains(x.Key)).Select(x => x.Value) .Where(x => x.Implementation.Name == error.Implementation.Name); PopulateRaceBarriers(barriers, error as RaceError); } else { DivergenceError divergence = error as DivergenceError; List <Barrier> final_barriers = new List <Barrier>(); foreach (Barrier barrier in ProgramMetadata.Barriers.Values) { LocationChain chain = ProgramMetadata.Locations[barrier.SourceLocation]; if (chain.Equals(divergence.Location)) { AddBarrier(final_barriers, barrier); } } divergence.Barriers = final_barriers; } }
/// <summary> /// Filter the barriers based on the source information. /// </summary> /// <param name="start">The start location.</param> /// <param name="end">The end location.</param> /// <returns>The barriers to be considered.</returns> private List <Barrier> FilterBarriers(SourceLocationInfo start, SourceLocationInfo end) { List <Barrier> location_barriers = new List <Barrier>(); foreach (Barrier barrier in ProgramMetadata.Barriers.Values) { LocationChain chain = ProgramMetadata.Locations[barrier.SourceLocation]; if (start != null && end != null) { if (chain.IsBetween(start, end)) { AddBarrier(location_barriers, barrier); } } } return(location_barriers); }
/// <summary> /// Generate a summary for the barrier changes. /// </summary> /// <param name="assignments">The assignments.</param> /// <param name="filename">The file path.</param> /// <return>The changes.</return> public IEnumerable <string> GenerateSummary(Dictionary <string, bool> assignments, string filename) { int repaired_weight = 0; foreach (string barrierName in assignments.Where(x => x.Value == true).Select(x => x.Key)) { Barrier barrier = ProgramMetadata.Barriers[barrierName]; repaired_weight += barrier.Weight; } int source_weight = 0; foreach (Barrier barrier in ProgramMetadata.Barriers.Values) { if (!barrier.Generated) { source_weight += barrier.Weight; } } Logger.Log($"SourceWeight;{source_weight}"); Logger.Log($"RepairedWeight;{repaired_weight}"); List <string> lines = new List <string>(); List <string> changes = new List <string>(); int solutionCalls = 0; int solutionGrid = 0; int solutionLoop = 0; if (source_weight != repaired_weight) { foreach (string barrierName in assignments.Keys) { Barrier barrier = ProgramMetadata.Barriers[barrierName]; LocationChain chain = ProgramMetadata.Locations[barrier.SourceLocation]; string location = chain.ToString(); if (!barrier.Generated && !assignments[barrierName]) { string message = string.Format( "Remove the {0}barrier at location {1}.", barrier.GridLevel ? "grid-level " : string.Empty, location); lines.Add(message); changes.Add(location); if (chain.Count > 1) { solutionCalls++; } } else if (barrier.Generated && assignments[barrierName]) { string loopMessage = ProgramMetadata.LoopBarriers.SelectMany(x => x.Value).Any(x => x.Name == barrierName) ? barrier.LoopDepth == 0 ? " outside the loop" : " inside the loop" : string.Empty; string message = string.Format( "Add a {0}barrier at location {1}{2}.", barrier.GridLevel ? "grid-level " : string.Empty, location, loopMessage); lines.Add(message); changes.Add(location); solutionCalls += chain.Count > 1 ? 1 : 0; solutionGrid += barrier.GridLevel ? 1 : 0; solutionLoop += barrier.LoopDepth > 0 ? 1 : 0; } } } Logger.Log($"SolutionCalls;{solutionCalls}"); Logger.Log($"SolutionGrid;{solutionGrid}"); Logger.Log($"SolutionLoop;{solutionLoop}"); if (lines.Any()) { File.AppendAllLines(filename, lines.Distinct()); } return(changes.Distinct()); }