/// <summary> /// Checks liveness at a trace cycle. /// </summary> /// <param name="root">Cycle start</param> internal void CheckLivenessAtTraceCycle(Fingerprint root, Trace trace) { var cycle = new List<TraceStep>(); do { Output.Debug(DebugType.Liveness, "<LivenessDebug> Cycle contains {0}.", trace.Peek().Fingerprint.ToString()); cycle.Add(trace.Pop()); } while (trace.Peek() != null && !trace.Peek().Fingerprint.Equals(root)); if (!this.IsSchedulingFair(cycle)) { Output.Debug(DebugType.Liveness, "<LivenessDebug> Scheduling in cycle is unfair."); return; } else if (!this.IsNondeterminismFair(cycle)) { Output.Debug(DebugType.Liveness, "<LivenessDebug> Nondeterminism in cycle is unfair."); return; } Output.Debug(DebugType.Liveness, "<LivenessDebug> Cycle execution is fair."); var hotMonitors = this.GetHotMonitors(cycle); foreach (var monitor in hotMonitors) { string message = Output.Format("Monitor '{0}' detected infinite execution that " + "violates a liveness property.", monitor.GetType().Name); PSharpRuntime.BugFinder.NotifyAssertionFailure(message, false); } PSharpRuntime.BugFinder.Stop(); }