/// <summary> /// Returns a string representation of the minimal critical fault sets. /// </summary> public override string ToString() { var builder = new StringBuilder(); var percentage = CheckedSets.Count / (float)(1 << Faults.Count()) * 100; builder.AppendLine(); builder.AppendLine("======================================================================="); builder.AppendLine("======= Deductive Cause Consequence Analysis: Results ======="); builder.AppendLine("======================================================================="); builder.AppendLine(); if (Exceptions.Any()) { builder.AppendLine("*** Warning: Unhandled exceptions have been thrown during the analysis. ***"); builder.AppendLine(); } if (!IsComplete) { builder.AppendLine("*** Warning: Analysis might be incomplete; not all fault sets have been checked. ***"); builder.AppendLine(); } Func <IEnumerable <Fault>, string> getFaultString = faults => String.Join(", ", faults.Select(fault => fault.Name).OrderBy(name => name)); builder.AppendFormat("Elapsed Time: {0}", Time); builder.AppendLine(); builder.AppendFormat("Fault Count: {0}", Faults.Count()); builder.AppendLine(); builder.AppendFormat("Faults: {0}", getFaultString(Faults)); builder.AppendLine(); if (ForcedFaults.Any()) { builder.AppendFormat("Forced Faults: {0}", getFaultString(ForcedFaults)); builder.AppendLine(); } if (SuppressedFaults.Any()) { builder.AppendFormat("Suppressed Faults: {0}", getFaultString(SuppressedFaults)); builder.AppendLine(); } builder.AppendLine(); builder.AppendFormat("Checked Fault Sets: {0} ({1:F0}% of all fault sets)", CheckedSets.Count, percentage); builder.AppendLine(); builder.AppendFormat("Minimal Critical Sets: {0}", MinimalCriticalSets.Count); builder.AppendLine(); builder.AppendLine(); var i = 1; foreach (var criticalSet in MinimalCriticalSets) { builder.AppendFormat(" ({1}) {{ {0} }}", String.Join(", ", criticalSet.Select(fault => fault.Name).OrderBy(name => name)), i++); Exception e; if (Exceptions.TryGetValue(criticalSet, out e)) { builder.AppendLine(); builder.AppendFormat( " An unhandled exception of type {0} was thrown while checking the fault set: {1}", e.GetType().FullName, e.Message); } builder.AppendLine(); } return(builder.ToString()); }
/// <summary> /// Returns a string representation of the minimal critical fault sets. /// </summary> public override string ToString() { var builder = new StringBuilder(); var percentage = CheckedSetCount / (double)(1L << Faults.Count()) * 100; var cardinalitySum = MinimalCriticalSets.Sum(set => set.Count); var minimalSetCardinalityAverage = cardinalitySum == 0 ? 0 : cardinalitySum / (double)MinimalCriticalSets.Count; builder.AppendLine(); builder.AppendLine("======================================================================="); builder.AppendLine("======= Deductive Cause Consequence Analysis: Results ======="); builder.AppendLine("======================================================================="); builder.AppendLine(); if (Exceptions.Any()) { builder.AppendLine("*** Warning: Unhandled exceptions have been thrown during the analysis. ***"); builder.AppendLine(); } if (!IsComplete) { builder.AppendLine("*** Warning: Analysis might be incomplete; not all fault sets have been checked. ***"); builder.AppendLine(); } Func <IEnumerable <Fault>, string> getFaultString = faults => String.Join(", ", faults.Select(fault => fault.Name).OrderBy(name => name)); builder.AppendLine($"Elapsed Time: {Time}"); builder.AppendLine($"Fault Count: {Faults.Count()}"); builder.AppendLine($"Faults: {getFaultString(Faults)}"); if (ForcedFaults.Any()) { builder.AppendLine($"Forced Faults: {getFaultString(ForcedFaults)}"); } if (SuppressedFaults.Any()) { builder.AppendLine($"Suppressed Faults: {getFaultString(SuppressedFaults)}"); } builder.AppendLine(); builder.AppendLine($"Checked Fault Sets: {CheckedSetCount} ({percentage:F0}% of all fault sets)"); builder.AppendLine($"Minimal Critical Sets: {MinimalCriticalSets.Count}"); builder.AppendLine($"Average Minimal Critical Set Cardinality: {minimalSetCardinalityAverage:F1}"); builder.AppendLine(); var i = 1; foreach (var criticalSet in MinimalCriticalSets) { builder.AppendFormat(" ({1}) {{ {0} }}", String.Join(", ", criticalSet.Select(fault => fault.Name).OrderBy(name => name)), i++); Exception e; if (Exceptions.TryGetValue(criticalSet, out e)) { builder.AppendLine(); builder.Append( $" An unhandled exception of type {e.GetType().FullName} was thrown while checking the fault set: {e.Message}"); } builder.AppendLine(); } var heuristicCount = Heuristics.Count(); if (heuristicCount != 0) { builder.AppendLine(); if (HeuristicSuggestionCount == 0) { builder.AppendLine("No suggestions were made by the heuristics."); } else { var nonTriviallyCritical = HeuristicSuggestionCount - HeuristicNonTrivialSafeCount - HeuristicTrivialCount; var percentageTrivial = HeuristicTrivialCount / (double)(HeuristicSuggestionCount) * 100; var percentageNonTrivialSafe = HeuristicNonTrivialSafeCount / (double)(HeuristicSuggestionCount) * 100; var percentageNonTrivialCritical = nonTriviallyCritical / (double)(HeuristicSuggestionCount) * 100; builder.AppendLine($"Of {HeuristicSuggestionCount} fault sets suggested by {heuristicCount} heuristics"); builder.AppendLine($" {HeuristicTrivialCount} ({percentageTrivial:F0}%) were trivially safe or trivially critical,"); builder.AppendLine($" {HeuristicNonTrivialSafeCount} ({percentageNonTrivialSafe:F0}%) were non-trivially safe, and"); builder.AppendLine($" {nonTriviallyCritical} ({percentageNonTrivialCritical:F0}%) were non-trivially critical."); builder.AppendLine($"In total, {TrivialChecksCount} trivial checks were performed."); } } return(builder.ToString()); }