/// <summary> /// Populates the divergence information. /// </summary> /// <param name="example">The counter example.</param> /// <param name="error">The divergence error.</param> public void PopulateDivergenceInformation(CallCounterexample example, DivergenceError error) { CallCmd call = example.FailingCall; SourceLocationInfo source = new SourceLocationInfo(GetAttributes(call), GetSourceFileName(), call.tok); error.Location = source; }
/// <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> /// Generates the errors from the counter example. /// </summary> /// <param name="example">The counter example.</param> /// <param name="implementation">The implementation.</param> /// <returns>The error.</returns> private IEnumerable <Error> GenerateErrors(Counterexample example, Implementation implementation) { List <Error> errors = new List <Error>(); if (example is CallCounterexample) { CallCounterexample callCounterexample = example as CallCounterexample; if (QKeyValue.FindBoolAttribute(callCounterexample.FailingRequires.Attributes, "barrier_divergence")) { DivergenceError divergence = new DivergenceError(example, implementation); ErrorReporter reporter = new ErrorReporter(program, implementation.Name); reporter.PopulateDivergenceInformation(callCounterexample, divergence); IdentifyVariables(divergence); errors.Add(divergence); return(errors); } else if (QKeyValue.FindBoolAttribute(callCounterexample.FailingRequires.Attributes, "race")) { RaceError template = new RaceError(example, implementation); ErrorReporter reporter = new ErrorReporter(program, implementation.Name); IEnumerable <RaceError> races = reporter.GetRaceInformation(callCounterexample, template); foreach (RaceError race in races) { IdentifyVariables(race); } errors.AddRange(races); return(errors); } } errors.Add(new Error(example, implementation)); return(errors); }