public bool IsSafe(DcrGraph safeForDcrGraph) { //acyclic var dependencyGraph = this.BuildDependencyGraph(); var cycleChecker = new CycleChecker(); var cycle = cycleChecker.ExistsCycleConditionMilestone(dependencyGraph); var cycleResponse = cycleChecker.ExistsCycleResponse(dependencyGraph); if (cycle != null || cycleResponse != null) { return(false); } // no include, exclude or response to any activity if (dependencyGraph.Any(x => x._relationsOutgoing.Any(y => y.Type == Relation.RelationType.Include || y.Type == Relation.RelationType.Exclude || y.Type == Relation.RelationType.Response))) { return(false); } // np-hard? Check any outgoing condition/milestone reachable if (dependencyGraph.Any(x => x._relationsOutgoing.Any(y => (y.Type == Relation.RelationType.Condition || y.Type == Relation.RelationType.Milestone) && !ReachableFromTo(y.From, y.To, safeForDcrGraph)))) { return(false); } return(true); }
private void FindDeadlocks() { var cycleChecker = new CycleChecker(); foreach (var dcrGraph in DcrGraphs) { var cycles = cycleChecker.GetAllCycleConditionMilestone(dcrGraph.Activities); if (cycles != null) { var breakAble = false; // check any event included and no incoming except include breakAble = dcrGraph.Activities.Any(x => !x.Excluded && x._relationsIncoming.All(y => y.Type == Relation.RelationType.Include)); if (breakAble) { return; } // check exists safe event which can not be excluded foreach (var activity in dcrGraph.Activities) { if (activity.IsSafe(dcrGraph) && activity._relationsIncoming.All(x => x.Type != Relation.RelationType.Exclude)) { breakAble = true; } } if (breakAble) { return; } var cyclesBreakAble = new List <bool>(); foreach (var cycle in cycles) { breakAble = cycle.Any(x => x._relationsIncoming.All(y => y.Type != Relation.RelationType.Include) && x._relationsIncoming.All(y => y.Type == Relation.RelationType.Exclude && y.From.IsSafe(dcrGraph))); cyclesBreakAble.Add(breakAble); } for (var index = 0; index < cyclesBreakAble.Count; index++) { var breakable = cyclesBreakAble[index]; if (breakable) { continue; } var cycle = cycles[index]; if (cycle.All(x => !x.Pending && x._relationsIncoming.All(y => y.Type != Relation.RelationType.Response) && dcrGraph.Activities.All(y => !y.Pending))) { cyclesBreakAble[index] = true; } } for (var index = 0; index < cyclesBreakAble.Count; index++) { var b = cyclesBreakAble[index]; var cycle = cycles[index]; if (!b) { Deadlocks.Add(new Tuple <DcrGraph, List <Activity> >(dcrGraph, cycle)); } } } } }
private void FindLivelocks() { var cycleChecker = new CycleChecker(); foreach (var dcrGraph in DcrGraphs) { var deadCycles = cycleChecker.GetAllCycleConditionMilestone(dcrGraph.Activities); var liveCycles = cycleChecker.GetAllCycleResponse(dcrGraph.Activities); if (liveCycles == null && deadCycles == null) { return; } var noDead = new List <bool>(); if (deadCycles != null) { foreach (var deadCycle in deadCycles) { if (deadCycle.All(x => !x.Pending && x._relationsIncoming.All(y => y.Type != Relation.RelationType.Response))) { if (deadCycle.Any(x => x._relationsOutgoing.Any(y => (y.Type == Relation.RelationType.Condition || y.Type == Relation.RelationType.Milestone) && !y.To.Id.Equals(y.From.Id)))) { noDead.Add(false); continue; } noDead.Add(true); continue; } var possiblyPending = deadCycle.Where(x => x.Pending || x._relationsIncoming.Any(y => y.Type == Relation.RelationType.Response)).ToList(); if (possiblyPending.Any()) { foreach (var activity in possiblyPending) { var graphWithNoExcludeToActivityBeingTested = new DcrGraph(dcrGraph.EditWindowString, new List <string>(), dcrGraph.EditWindowString, "graphWithNoRelationsToActivityBeingTested"); var perhapsSafeActivity = graphWithNoExcludeToActivityBeingTested.Activities.Where(x => x._relationsOutgoing.Any(y => y.To.Id.Equals(activity.Id) && y.Type == Relation.RelationType.Exclude)).ToList(); foreach (var activity1 in perhapsSafeActivity) { activity1._relationsOutgoing.Remove(activity1._relationsOutgoing.First(x => x.Type == Relation.RelationType.Exclude && x.To.Id.Equals(activity.Id))); } var anySafeExlude = perhapsSafeActivity.Any(x => x.IsSafe(graphWithNoExcludeToActivityBeingTested) && x._relationsIncoming.All(y => y.Type != Relation.RelationType.Exclude)); if (!(activity.Excluded || anySafeExlude)) { noDead.Add(false); break; } else { noDead.Add(true); } } //noDead.Add(true); } else { noDead.Add(true); } } for (int i = 0; i < deadCycles.Count; i++) { var cycle = deadCycles[i]; bool live = noDead[i]; if (!live) { Livelokcs.Add(new Tuple <DcrGraph, List <Activity> >(dcrGraph, cycle)); } } } var noLive = new List <bool>(); if (liveCycles != null) { foreach (var liveCycle in liveCycles) { // all safe if (liveCycle.All(x => x.IsSafe(dcrGraph))) { noLive.Add(true); continue; } // exist always excluded never included in circle if (liveCycle.Any(x => (x.Excluded && x._relationsIncoming.All(y => y.Type == Relation.RelationType.Include)) || x._relationsIncoming.Any(y => y.Type == Relation.RelationType.Exclude && y.From.IsSafe(CreateXE(dcrGraph, y.From)) && y.From._relationsIncoming.All(z => z.Type != Relation.RelationType.Exclude)) && x._relationsIncoming.All(c => c.Type != Relation.RelationType.Include))) { noLive.Add(true); continue; } noLive.Add(false); } for (int i = 0; i < liveCycles.Count; i++) { var cycle = liveCycles[i]; bool live = noLive[i]; if (!live) { Livelokcs.Add(new Tuple <DcrGraph, List <Activity> >(dcrGraph, cycle)); } } } } }