/// <summary> /// Identifies parallels in the graph /// </summary> /// <param name="graphNode">Analyzed node</param> /// <author>Krystian Zielonka, Thomas Meents, Bernd Nottbeck</author> private bool CheckAndCut(InductiveMinerGraphNode graphNode) { bool wasSplit = false; if (graphNode.FollowerList.Count > 1) { List <InductiveMinerRow> followerList = graphNode.FollowerList; List <InductiveMinerRow> deleteList = new List <InductiveMinerRow>(); foreach (InductiveMinerRow row in followerList) { InductiveMinerRow currentRow = row.ToNode.FollowerList.FirstOrDefault(); if (currentRow.ToNode.GetMyDirectNodes().Contains(currentRow.FromNode)) { deleteList.Add(currentRow); } } wasSplit = deleteList.Any(); if (wasSplit) { foreach (InductiveMinerRow row in deleteList) { row.FromNode.DeleteFollower(row); } InductiveMinerRow lastRow = deleteList.Last(); newStart.AddDirectFollower(lastRow.FromNode); newStart.AddEventualFollower(lastRow.FromNode); graphNode.DeleteFollower(graphNode.GetRowWithFollower(lastRow.FromNode)); graphNode.ReBuildeEventualFollower(null); graphNode.CleanUpHelperList(null); } } return(wasSplit); }
/// <summary> /// Recursive procedure to identify sequence cuts /// </summary> /// <param name="graphNode">Analyzed node</param> /// <author>Krystian Zielonka, Bernd Nottbeck</author> private bool CheckXorCut(InductiveMinerGraphNode graphNode) { List <InductiveMinerGraphNode> followerList = graphNode.GetMyDirectNodes(); List <InductiveMinerRow> deleteList = new List <InductiveMinerRow>(); bool bo = false; bool foundone = false; bool goOn = true; if (graphNode.FollowerList.Count > 1) { List <InductiveMinerRow> .Enumerator e = graphNode.FollowerList.GetEnumerator(); e.MoveNext(); do { if (!e.Current.ToNode.FollowerContains(followerList)) { if (foundone) { goOn = false; deleteList.Add(e.Current); } foundone = true; } if (goOn) { goOn = e.MoveNext(); } } while (goOn); e.Dispose(); foreach (InductiveMinerRow deleteRow in deleteList) { newStart.AddDirectFollower(deleteRow.ToNode); foreach (InductiveMinerRow row in deleteRow.ToNode.EventualFollowerList) { if (!newStart.GetMyEventualNodes().Contains(row.ToNode)) { newStart.EventualFollowerList.Add(new InductiveMinerRow(newStart, row.ToNode)); } } graphNode.WasCut = true; graphNode.DeleteFollower(deleteRow); bo = true; } if (bo) { newStart.ReBuildeEventualFollower(null); newStart.CleanUpHelperList(null); graphNode.ReBuildeEventualFollower(null); graphNode.CleanUpHelperList(null); } return(bo); } else { return(false); } }
/// <summary> /// Recursive procedure to identify sequence cuts /// </summary> /// <param name="graphNode">Analyzed node</param> /// <author>Krystian Zielonka, Bernd Nottbeck</author> private bool CheckXorCut(InductiveMinerGraphNode graphNode) { List<InductiveMinerGraphNode> followerList = graphNode.GetMyDirectNodes(); List<InductiveMinerRow> deleteList = new List<InductiveMinerRow>(); bool bo = false; bool foundone = false; bool goOn = true; if (graphNode.FollowerList.Count > 1) { List<InductiveMinerRow>.Enumerator e = graphNode.FollowerList.GetEnumerator(); e.MoveNext(); do { if (!e.Current.ToNode.FollowerContains(followerList)) { if (foundone) { goOn = false; deleteList.Add(e.Current); } foundone = true; } if (goOn) { goOn = e.MoveNext(); } } while (goOn); e.Dispose(); foreach (InductiveMinerRow deleteRow in deleteList) { newStart.AddDirectFollower(deleteRow.ToNode); foreach (InductiveMinerRow row in deleteRow.ToNode.EventualFollowerList) { if (!newStart.GetMyEventualNodes().Contains(row.ToNode)) newStart.EventualFollowerList.Add(new InductiveMinerRow(newStart, row.ToNode)); } graphNode.WasCut = true; graphNode.DeleteFollower(deleteRow); bo = true; } if (bo) { newStart.ReBuildeEventualFollower(null); newStart.CleanUpHelperList(null); graphNode.ReBuildeEventualFollower(null); graphNode.CleanUpHelperList(null); } return bo; } else return false; }
/// <summary> /// Identifies possible cuts and recursively generates the tree. /// </summary> public void DivideAndConquer() { if (Operation == OperationsEnum.isUnkown) { GraphNode.ReBuildeEventualFollower(null); GraphNode.CleanUpHelperList(null); foreach (InductiveMinerGraphNode nody in GraphNode.GetMyEventualNodes()) { nody.ReBuildeEventualFollower(null); nody.CleanUpHelperList(null); } if (GraphNode.EventualFollowerList.Count <= 1) { Operation = OperationsEnum.isLeaf; } } if (Operation != OperationsEnum.isLeaf) { if (CheckSequenceCut()) { newStart.ReBuildeEventualFollower(null); newStart.CleanUpHelperList(null); foreach (InductiveMinerGraphNode nody in newStart.GetMyEventualNodes()) { nody.ReBuildeEventualFollower(null); nody.CleanUpHelperList(null); } LeftLeaf = new InductiveMinerTreeNode(petriNet, GraphNode, startEvent); RightLeaf = new InductiveMinerTreeNode(petriNet, newStart, newStart.Name); Operation = OperationsEnum.isSequence; } else if (CheckXorCut(GraphNode)) { newStart.ReBuildeEventualFollower(null); newStart.CleanUpHelperList(null); foreach (InductiveMinerGraphNode nody in newStart.GetMyEventualNodes()) { nody.ReBuildeEventualFollower(null); nody.CleanUpHelperList(null); } LeftLeaf = new InductiveMinerTreeNode(petriNet, GraphNode, startEvent); RightLeaf = new InductiveMinerTreeNode(petriNet, newStart, newStart.Name); Operation = OperationsEnum.isXOR; } else if (CheckLoopCut(GraphNode)) { newStart.ReBuildeEventualFollower(null); newStart.CleanUpHelperList(null); foreach (InductiveMinerGraphNode nody in newStart.GetMyEventualNodes()) { nody.ReBuildeEventualFollower(null); nody.CleanUpHelperList(null); } LeftLeaf = new InductiveMinerTreeNode(petriNet, GraphNode, startEvent); RightLeaf = new InductiveMinerTreeNode(petriNet, newStart, newStart.Name); Operation = OperationsEnum.isLoop; } else if (CheckAndCut(GraphNode)) { newStart.ReBuildeEventualFollower(null); newStart.CleanUpHelperList(null); foreach (InductiveMinerGraphNode nody in newStart.GetMyEventualNodes()) { nody.ReBuildeEventualFollower(null); nody.CleanUpHelperList(null); } LeftLeaf = new InductiveMinerTreeNode(petriNet, GraphNode, startEvent); RightLeaf = new InductiveMinerTreeNode(petriNet, newStart, newStart.Name); Operation = OperationsEnum.isParallel; } } else { if (GraphNode.FollowerList.Count > 0) { Event = GraphNode.FollowerList[0].ToNode.Name; } } }
/// <summary> /// Identifies parallels in the graph /// </summary> /// <param name="graphNode">Analyzed node</param> /// <author>Krystian Zielonka, Thomas Meents, Bernd Nottbeck</author> private bool CheckAndCut(InductiveMinerGraphNode graphNode) { bool wasSplit = false; if (graphNode.FollowerList.Count > 1) { List<InductiveMinerRow> followerList = graphNode.FollowerList; List<InductiveMinerRow> deleteList = new List<InductiveMinerRow>(); foreach (InductiveMinerRow row in followerList) { InductiveMinerRow currentRow = row.ToNode.FollowerList.FirstOrDefault(); if (currentRow.ToNode.GetMyDirectNodes().Contains(currentRow.FromNode)) { deleteList.Add(currentRow); } } wasSplit = deleteList.Any(); if (wasSplit) { foreach (InductiveMinerRow row in deleteList) { row.FromNode.DeleteFollower(row); } InductiveMinerRow lastRow = deleteList.Last(); newStart.AddDirectFollower(lastRow.FromNode); newStart.AddEventualFollower(lastRow.FromNode); graphNode.DeleteFollower(graphNode.GetRowWithFollower(lastRow.FromNode)); graphNode.ReBuildeEventualFollower(null); graphNode.CleanUpHelperList(null); } } return wasSplit; }