/// <summary> /// Check if activity from is the nearest output of activity activity to /// </summary> /// <param name="dependencyGraph">Dependency graph</param> /// <param name="from">From index</param> /// <param name="to">To index</param> /// <param name="tracePosition">Trace position</param> /// <param name="trace">Trace</param> /// <returns>Whether activity from is the nearest output of activity to</returns> private bool IsNearestOutput(DependencyGraph dependencyGraph, int from, int to, int tracePosition, WorkflowTrace trace) { for (int i = tracePosition - 1; i >= 0; i--) { var iActivity = ActivityIndices[trace.Activities[i]]; if (iActivity == to) { for (int j = i + 1; j < tracePosition; j++) { var jActivity = ActivityIndices[trace.Activities[j]]; if (dependencyGraph.InputActivities[jActivity].Contains(iActivity) && dependencyGraph.InputActivities[from].Contains(jActivity)) { return(false); } } return(true); } if (trace.Activities[i] == trace.Activities[tracePosition]) //Same activity, which we started with { return(false); } } //No occurrence of to activity return(false); }
/// <param name="trace">Workflow trace</param> /// <param name="pNet">Petri net</param> /// <param name="worstCostOnModel">Worst cost on the model</param> /// <param name="traceMoveCost">Trace move cost</param> /// <param name="modelMoveCost">Model move cost</param> public AlignmentOnTrace(WorkflowTrace trace, PetriNet pNet, double worstCostOnModel, int traceMoveCost = 1, int modelMoveCost = 1) { InitCosts(traceMoveCost, modelMoveCost); InitTransitionsAndOptimalCost(trace, pNet, traceMoveCost, modelMoveCost); WorstCost = worstCostOnModel + AlignmentUtils.ComputeWorstCostOfTrace(trace, traceMoveCost); ComputeFitness(); }
/// <summary> /// Trace /// </summary> /// <param name="workflowOid">Workflow Oid</param> /// <param name="action">Action</param> /// <param name="code">Code</param> /// <param name="result">Result</param> /// <param name="user">User</param> /// <param name="msg">Msg</param> /// <param name="type">Type</param> public void Trace(Guid workflowOid, ActionTrace action, string code, string result, string user, string msg, TraceEventType type) { using (var uofw = new FlowTasksUnitOfWork()) { var wfd = uofw.WorkflowDefinitions.First(w => w.WorkflowOid == workflowOid); var eventType = type.ToString(); var tre = uofw.TraceEvents.First(e => e.Type == eventType); var t = new WorkflowTrace { Message = msg.Substring(0, Math.Min(msg.Length, 500)), TraceEvent = tre, User = string.IsNullOrWhiteSpace(user) ? string.Empty : user, When = DateTime.Now, WorkflowDefinition = wfd, Action = action.ToString(), Code = code, Result = result }; uofw.WorkflowTraces.Insert(t); uofw.Commit(); } }
/// <summary> /// Compute optimal alignment based on a trace and a Petri net /// </summary> /// <param name="trace">Workflow trace</param> /// <param name="pNet">Petri net</param> /// <param name="traceMoveCost">Trace move cost</param> /// <param name="modelMoveCost">Model move cost</param> /// <returns>Alignment on trace</returns> public static List <STransition> OptimalAlignmentOnTrace(WorkflowTrace trace, PetriNet pNet, int traceMoveCost = 1, int modelMoveCost = 1) { var tracePNet = MakePNetFromTrace(trace); var syncNet = new SynchronousProductNet(tracePNet, pNet, traceMoveCost, modelMoveCost); return(FindOptimalAlignment(syncNet)); }
private WorkflowTrace MakeTrace() { // Arrange WorkflowTrace trace = new WorkflowTrace("1"); trace.AddActivities(new List <string> { "act1", "act2", "act3", "act4", "act5" }); return(trace); }
/// <summary> /// Replays a given workflow trace through the Petri Net diagnostics overlay while setting diagnostics info for given trace. /// </summary> /// <param name="trace">A WorkflowTrace to be replayed.</param> public void ReplayTrace(WorkflowTrace trace) { SetupStartPlace(); foreach (string activity in trace.Activities) { Fire(PetriNet.Transitions.Find(a => a.Activity == activity)); } CleanUpEndPlace(); SetRemnants(); }
/// <summary> /// Construct Petri net from a trace /// </summary> /// <param name="trace">Workflow trace</param> /// <returns>Petri net of trace</returns> public static PetriNet MakePNetFromTrace(WorkflowTrace trace) { var places = new List <IPlace> { new Place("p0'") }; var transitions = new List <ITransition>(); var i = 1; foreach (var activity in trace.Activities) { places.Add(new Place("p" + i + "'")); transitions.Add(new Transition("t" + (i - 1) + "'", activity)); transitions[^ 1].InputPlaces.Add(places[^ 2]);
public void SyncNetAdvancedCustom() { // Arrange var trace = new WorkflowTrace("0"); trace.Activities.Add("register"); trace.Activities.Add("decide"); trace.Activities.Add("register"); trace.Activities.Add("send money"); trace.Activities.Add("inform acceptance"); var tNet = AlignmentUtils.MakePNetFromTrace(trace); List <ITransition> transitions = new List <ITransition>(); List <IPlace> places = new List <IPlace>(); for (int i = 1; i < 13; i++) { places.Add(new Place("p" + i)); } transitions.Add(new Transition("t1", "register")); transitions[^ 1].InputPlaces.Add(places[0]);
/// <summary> /// Initialize Transitions and OptimalCost /// </summary> /// <param name="trace">Workflow trace</param> /// <param name="pNet">Petri net</param> /// <param name="traceMoveCost">Trace move cost</param> /// <param name="modelMoveCost">Model move cost</param> private void InitTransitionsAndOptimalCost(WorkflowTrace trace, PetriNet pNet, int traceMoveCost, int modelMoveCost) { Transitions = AlignmentUtils.OptimalAlignmentOnTrace(trace, pNet, traceMoveCost, modelMoveCost); OptimalCost = AlignmentUtils.ComputeCostOfAlignment(Transitions); }
/// <summary> /// Find input binding candidate /// </summary> /// <param name="dependencyGraph">Depdendency graph</param> /// <param name="from">From index</param> /// <param name="tracePosition">Position in the trace</param> /// <param name="trace">Trace</param> /// <returns>Input binding candidate</returns> private HashSet <int> InBindCandidate(DependencyGraph dependencyGraph, int from, int tracePosition, WorkflowTrace trace) { var bindCandidate = new HashSet <int>(); foreach (var to in dependencyGraph.InputActivities[from]) { if (IsNearestOutput(dependencyGraph, from, to, tracePosition, trace)) { bindCandidate.Add(to); } } return(bindCandidate); }