示例#1
0
        /// <summary>
        /// Starts the mining process
        /// </summary>
        /// <returns>Process model</returns>
        /// <author>Krystian Zielonka, Thomas Meents, Bernd Nottbeck</author>
        public override ProcessModel Mine()
        {
            if (_field == null)
            {
                throw new ArgumentNullException("field", "The field parameter was null");
            }

            var processingTimeStart = Process.GetCurrentProcess().TotalProcessorTime;

            DirectFrequency();
            EventualFrequency();

            EventDictionary = EliminateInfrequentFirstListBuild(EventDictionary);

            BuildInitialDirectFollowGraph();
            BuildInitialEventualFollowGraph();

            foreach (KeyValuePair <Event, InductiveMinerGraphNode> pair in EventDictionary)
            {
                pair.Value.ReBuildeEventualFollower(null);
                pair.Value.CleanUpHelperList(null);
            }

            IMTree = new InductiveMinerTreeNode(IMPetriNet, EventDictionary[StartEvent], StartEvent);

            GeneratePetriNet();

            _field.ProcessModel = IMPetriNet;

            EndLog(processingTimeStart);
            return(_field.ProcessModel);
        }
        public void CreateExampleTree()
        {
            //linker Teil
            InductiveMinerTreeNode one = new InductiveMinerTreeNode(operation:OperationsEnum.isChoice);
            ExampleTree.LeftLeaf = one;
            InductiveMinerTreeNode two = new InductiveMinerTreeNode(new Event("D")) {Operation = OperationsEnum.isLeaf};
            one.RightLeaf = two;
            InductiveMinerTreeNode three = new InductiveMinerTreeNode(operation:OperationsEnum.isLoop);
            one.LeftLeaf = three;
            InductiveMinerTreeNode four = new InductiveMinerTreeNode(new Event("C")) {Operation = OperationsEnum.isLeaf};
            one.RightLeaf = four;
            InductiveMinerTreeNode five = new InductiveMinerTreeNode(operation:OperationsEnum.isSequence);
            three.LeftLeaf = five;
            InductiveMinerTreeNode six = new InductiveMinerTreeNode(new Event("A")) {Operation = OperationsEnum.isLeaf};
            five.LeftLeaf = six;
            InductiveMinerTreeNode seven = new InductiveMinerTreeNode(new Event("B")) { Operation = OperationsEnum.isLeaf };
            five.RightLeaf = seven;

            //rechter Teil
            InductiveMinerTreeNode eight = new InductiveMinerTreeNode(operation:OperationsEnum.isParallel);
            ExampleTree.RightLeaf = eight;
            InductiveMinerTreeNode nine = new InductiveMinerTreeNode(new Event("E")) {Operation = OperationsEnum.isLeaf};
            eight.LeftLeaf = nine;
            InductiveMinerTreeNode ten = new InductiveMinerTreeNode(new Event("F")) {Operation = OperationsEnum.isLeaf};
            eight.RightLeaf = ten;
        }
        /// <summary>
        /// Draws the transition with the incoming and outgoing places.
        /// </summary>
        /// <param name="node">Node that will be drawn</param>
        /// <param name="relayed">Relayed place. It will be the incoming place of the transition</param>
        /// <param name="overwriteOutgoingPlace">optional place that will be overwrite the outgoingplace</param>
        /// <param name="overwriteIncomingPlace">optional place that will be overwrite the Incomingplace</param>
        /// <returns>Outgoing Place of the drawn Transition</returns>
        /// <author>Thomas Meents</author>
        private Place DrawLeafPetrinet(InductiveMinerTreeNode node, Place relayed, Place overwriteOutgoingPlace = null, Place overwriteIncomingPlace = null)
        {
            if (!node.Operation.Equals(OperationsEnum.isLeaf))
            {
                throw new Exception("Only leafs can be drawn.");
            }

            Place outgoing = new Place();

            IMPetriNet.Places.Add(outgoing);

            if (overwriteIncomingPlace != null)
            {
                relayed = overwriteIncomingPlace;
            }

            Transition transition = new Transition(node.Event.Name)
            {
                IsDrawn = false
            };

            transition.AddIncomingPlace(relayed);
            transition.AddOutgoingPlace(outgoing);
            if (overwriteOutgoingPlace != null)
            {
                transition.OutgoingPlaces.Remove(outgoing);
                transition.OutgoingPlaces.Add(overwriteOutgoingPlace);
            }
            IMPetriNet.Transitions.Add(transition);

            return(outgoing);
        }
        /// <summary>
        /// Starts the mining process
        /// </summary>
        /// <returns>Process model</returns>
        /// <author>Krystian Zielonka, Thomas Meents, Bernd Nottbeck</author>
        public virtual ProcessModel Mine()
        {
            if (_field == null)
            {
                throw new ArgumentNullException("field", "The field parameter was null");
            }

            // Statistics
            var processingTimeStart = Process.GetCurrentProcess().TotalProcessorTime;

            DirectFrequency();
            EventualFrequency();
            BuildInitialDirectFollowGraph();
            BuildInitialEventualFollowGraph();

            IMTree = new InductiveMinerTreeNode(IMPetriNet, EventDictionary[StartEvent], StartEvent);

            GeneratePetriNet();

            FinishPetriNet();
            _field.ProcessModel = IMPetriNet;

            EndLog(processingTimeStart);
            return(_field.ProcessModel);
        }
        /// <summary>
        /// Starts the mining process
        /// </summary>
        /// <returns>Process model</returns>
        /// <author>Krystian Zielonka, Thomas Meents, Bernd Nottbeck</author>
        public override ProcessModel Mine()
        {
            if (_field == null)
                throw new ArgumentNullException("field", "The field parameter was null");

            var processingTimeStart = Process.GetCurrentProcess().TotalProcessorTime;

            DirectFrequency();
            EventualFrequency();

            EventDictionary = EliminateInfrequentFirstListBuild(EventDictionary);

            BuildInitialDirectFollowGraph();
            BuildInitialEventualFollowGraph();

            foreach (KeyValuePair<Event, InductiveMinerGraphNode> pair in EventDictionary)
            {
                pair.Value.ReBuildeEventualFollower(null);
                pair.Value.CleanUpHelperList(null);
            }

            IMTree = new InductiveMinerTreeNode(IMPetriNet, EventDictionary[StartEvent], StartEvent);

            GeneratePetriNet();

            _field.ProcessModel = IMPetriNet;

            EndLog(processingTimeStart);
            return _field.ProcessModel;
        }
 /// <summary>
 /// Constructor for a tree node
 /// </summary>
 /// <param name="inductiveMiner"></param>
 /// <param name="operation">node operation</param>
 /// <param name="associatedEvent"></param>
 /// <param name="right"></param>
 /// <param name="left"></param>
 /// <author>Thomas Meents, Bernd Nottbeck</author>
 public InductiveMinerTreeNode(InductiveMiner inductiveMiner, OperationsEnum operation, Event associatedEvent = null, InductiveMinerTreeNode right = null, InductiveMinerTreeNode left = null)
 {
     Operation = operation;
     LeftLeaf = left;
     RightLeaf = right;
     Event = associatedEvent;
     petriNet = inductiveMiner.IMPetriNet;
 }
示例#7
0
 /// <summary>
 /// Constructor for a tree node
 /// </summary>
 /// <param name="inductiveMiner"></param>
 /// <param name="operation">node operation</param>
 /// <param name="associatedEvent"></param>
 /// <param name="right"></param>
 /// <param name="left"></param>
 /// <author>Thomas Meents, Bernd Nottbeck</author>
 public InductiveMinerTreeNode(InductiveMiner inductiveMiner, OperationsEnum operation, Event associatedEvent = null, InductiveMinerTreeNode right = null, InductiveMinerTreeNode left = null)
 {
     Operation = operation;
     LeftLeaf  = left;
     RightLeaf = right;
     Event     = associatedEvent;
     petriNet  = inductiveMiner.IMPetriNet;
 }
        public void CreateExampleTree()
        {
            //linker Teil
            InductiveMinerTreeNode one = new InductiveMinerTreeNode(operation: OperationsEnum.isChoice);

            ExampleTree.LeftLeaf = one;
            InductiveMinerTreeNode two = new InductiveMinerTreeNode(new Event("D"))
            {
                Operation = OperationsEnum.isLeaf
            };

            one.RightLeaf = two;
            InductiveMinerTreeNode three = new InductiveMinerTreeNode(operation: OperationsEnum.isLoop);

            one.LeftLeaf = three;
            InductiveMinerTreeNode four = new InductiveMinerTreeNode(new Event("C"))
            {
                Operation = OperationsEnum.isLeaf
            };

            one.RightLeaf = four;
            InductiveMinerTreeNode five = new InductiveMinerTreeNode(operation: OperationsEnum.isSequence);

            three.LeftLeaf = five;
            InductiveMinerTreeNode six = new InductiveMinerTreeNode(new Event("A"))
            {
                Operation = OperationsEnum.isLeaf
            };

            five.LeftLeaf = six;
            InductiveMinerTreeNode seven = new InductiveMinerTreeNode(new Event("B"))
            {
                Operation = OperationsEnum.isLeaf
            };

            five.RightLeaf = seven;

            //rechter Teil
            InductiveMinerTreeNode eight = new InductiveMinerTreeNode(operation: OperationsEnum.isParallel);

            ExampleTree.RightLeaf = eight;
            InductiveMinerTreeNode nine = new InductiveMinerTreeNode(new Event("E"))
            {
                Operation = OperationsEnum.isLeaf
            };

            eight.LeftLeaf = nine;
            InductiveMinerTreeNode ten = new InductiveMinerTreeNode(new Event("F"))
            {
                Operation = OperationsEnum.isLeaf
            };

            eight.RightLeaf = ten;
        }
        public static InductiveMinerTreeNode CreateExampleSequence(InductiveMiner miner)
        {
            InductiveMinerTreeNode ExampleTree = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isSequence);
            InductiveMinerTreeNode one = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isSequence);
            ExampleTree.LeftLeaf = one;
            InductiveMinerTreeNode two = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isLeaf) { Event = new Event("A") };
            one.LeftLeaf = two;
            InductiveMinerTreeNode three = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isLeaf) { Event = new Event("B") };
            one.RightLeaf = three;
            InductiveMinerTreeNode four = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isLeaf) { Event = new Event("C") };
            ExampleTree.RightLeaf = four;

            return ExampleTree;
        }
        public static InductiveMinerTreeNode CreateExampleParallelXOR(InductiveMiner miner)
        {
            InductiveMinerTreeNode ExampleTree = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isSequence);

            InductiveMinerTreeNode one = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isLeaf) {Event =  new Event("A")};
            ExampleTree.LeftLeaf = one;
            InductiveMinerTreeNode two = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isParallel);
            ExampleTree.RightLeaf = two;
            InductiveMinerTreeNode three = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isLeaf) { Event = new Event("B") };
            two.LeftLeaf = three;
            InductiveMinerTreeNode four = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isXOR);
            two.RightLeaf = four;
            InductiveMinerTreeNode five = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isLeaf) { Event = new Event("C") };
            four.LeftLeaf = five;
            InductiveMinerTreeNode six = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isLeaf) { Event = new Event("D") };
            four.RightLeaf = six;

            return ExampleTree;
        }
        public static InductiveMinerTreeNode CreateExampleKnochenbruch(InductiveMiner miner)
        {
            InductiveMinerTreeNode ExampleTree = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isSequence);

            InductiveMinerTreeNode one = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isSequence);
            ExampleTree.LeftLeaf = one;
            InductiveMinerTreeNode two = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isLeaf) { Event = new Event("Befundung") };
            one.RightLeaf = two;
            InductiveMinerTreeNode three = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isSequence);
            one.LeftLeaf = three;
            InductiveMinerTreeNode four = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isParallel);
            three.RightLeaf = four;
            InductiveMinerTreeNode five = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isLeaf) { Event = new Event("Blutentnahme") };
            four.LeftLeaf = five;
            InductiveMinerTreeNode six = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isXOR);
            four.RightLeaf = six;
            InductiveMinerTreeNode seven = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isLeaf) { Event = new Event("Röntgen") };
            six.LeftLeaf = seven;
            InductiveMinerTreeNode eight = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isLeaf) { Event = new Event("MRT") };
            six.RightLeaf = eight;
            InductiveMinerTreeNode nine = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isSequence);
            three.LeftLeaf = nine;
            InductiveMinerTreeNode ten = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isLeaf) { Event = new Event("Aufnahme") };
            nine.LeftLeaf = ten;
            InductiveMinerTreeNode eleven = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isLeaf) { Event = new Event("Anamnese") };
            nine.RightLeaf = eleven;
            InductiveMinerTreeNode twelve = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isSequence);
            ExampleTree.RightLeaf = twelve;
            InductiveMinerTreeNode thirteen = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isLeaf) { Event = new Event("Operation") };
            twelve.LeftLeaf = thirteen;
            InductiveMinerTreeNode fourteen = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isSequence);
            twelve.RightLeaf = fourteen;
            InductiveMinerTreeNode fiveteen = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isLoop);
            fourteen.LeftLeaf = fiveteen;
            InductiveMinerTreeNode sixteen = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isLeaf) { Event = new Event("Entlassen") };
            fourteen.RightLeaf = sixteen;
            InductiveMinerTreeNode seventeen = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isLeaf) { Event = new Event("Verband anlegen") };
            fiveteen.LeftLeaf = seventeen;
            InductiveMinerTreeNode eigthteen = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isLeaf) { Event = new Event("Verband entfernen") };
            fiveteen.RightLeaf = eigthteen;

            return ExampleTree;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public static InductiveMinerTreeNode CreateExampleTree(InductiveMiner miner)
        {
            InductiveMinerTreeNode ExampleTree = new InductiveMinerTreeNode(miner,operation: OperationsEnum.isSequence);

            //linker Teil
            InductiveMinerTreeNode one = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isXOR);
            ExampleTree.LeftLeaf = one;
            InductiveMinerTreeNode two = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isLeaf) { Event = new Event("D") };
            one.RightLeaf = two;
            InductiveMinerTreeNode three = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isLoop);
            one.LeftLeaf = three;
            InductiveMinerTreeNode four = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isLeaf) { Event = new Event("C") };
            three.RightLeaf = four;
            InductiveMinerTreeNode five = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isSequence);
            three.LeftLeaf = five;

            InductiveMinerTreeNode six = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isLeaf) { Event = new Event("A") };
            five.LeftLeaf = six;
            InductiveMinerTreeNode seven = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isLeaf) { Event = new Event("B") };
            five.RightLeaf = seven;

            //rechter Teil
            InductiveMinerTreeNode eight = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isParallel);
            ExampleTree.RightLeaf = eight;
            InductiveMinerTreeNode nine = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isLeaf) { Event = new Event("E") };
            eight.LeftLeaf = nine;
            InductiveMinerTreeNode ten = new InductiveMinerTreeNode(miner, operation: OperationsEnum.isLeaf) { Event = new Event("F") };
            eight.RightLeaf = ten;

            return ExampleTree;
        }
        /// <summary>
        /// Starts the mining process
        /// </summary>
        /// <returns>Process model</returns>
        /// <author>Krystian Zielonka, Thomas Meents, Bernd Nottbeck</author>
        public virtual ProcessModel Mine()
        {
            if (_field == null)
                throw new ArgumentNullException("field", "The field parameter was null");

            // Statistics
            var processingTimeStart = Process.GetCurrentProcess().TotalProcessorTime;

            DirectFrequency();
            EventualFrequency();
            BuildInitialDirectFollowGraph();
            BuildInitialEventualFollowGraph();

            IMTree = new InductiveMinerTreeNode(IMPetriNet, EventDictionary[StartEvent], StartEvent);

            GeneratePetriNet();

            FinishPetriNet();
            _field.ProcessModel = IMPetriNet;

            EndLog(processingTimeStart);
            return _field.ProcessModel;
        }
示例#14
0
        /// <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>
        /// Recursively moves threw the tree and generates the IMPetrinet
        /// </summary>
        /// <param name="node">actual node</param>
        /// <param name="relayedPlace">Place that the process operator get</param>
        /// <param name="relayedOutgoingPlace">optional place that will be overwrite the outgoingplace</param>
        /// <param name="relayedIncomingPlace">optional place that will be overwrite the incomingplace</param>
        /// <author>Thomas Meents, Bernd Nottbeck</author>
        private Place TraverseTreePetrinet(InductiveMinerTreeNode node, Place relayedPlace, Place relayedOutgoingPlace = null, Place relayedIncomingPlace = null)
        {
            if (node.Operation.Equals(OperationsEnum.isLeaf))
            {
                return(DrawLeafPetrinet(node, relayedPlace, overwriteIncomingPlace: relayedIncomingPlace, overwriteOutgoingPlace: relayedOutgoingPlace));
            }

            if (node.Operation.Equals(OperationsEnum.isSequence))
            {
                if (node.LeftLeaf != null)
                {
                    Place temp = TraverseTreePetrinet(node.LeftLeaf, relayedPlace);
                    if (node.RightLeaf != null)
                    {
                        temp = TraverseTreePetrinet(node.RightLeaf, temp);
                    }
                    return(temp);
                }
            }
            else if (node.Operation.Equals(OperationsEnum.isXOR))
            {
                if (node.LeftLeaf != null)
                {
                    Place tempXORExitPlace = TraverseTreePetrinet(node.LeftLeaf, relayedPlace);

                    if (node.RightLeaf == null)
                    {
                        return(null);
                    }

                    Place newPlace = TraverseTreePetrinet(node.RightLeaf, tempXORExitPlace, relayedIncomingPlace: relayedPlace, relayedOutgoingPlace: tempXORExitPlace);

                    if (tempXORExitPlace != null)
                    {
                        return(tempXORExitPlace);
                    }
                    return(newPlace);
                }
            }
            else if (node.Operation.Equals(OperationsEnum.isLoop))
            {
                Place tempLoopEntrancePlace = relayedPlace;

                if (node.LeftLeaf != null)
                {
                    Place temp = TraverseTreePetrinet(node.LeftLeaf, relayedPlace);


                    Place tempLoopExitPlace = temp;

                    if (node.RightLeaf != null)
                    {
                        //prevents a Nullpointer-Exception if the first Place is a Loop.
                        if (tempLoopEntrancePlace != IMPetriNet.Places[0])
                        {
                            temp = TraverseTreePetrinet(node.RightLeaf, temp);
                            IMPetriNet.AddTransition("Loop", incomingPlace: temp, outgoingPlace: tempLoopEntrancePlace,
                                                     isLoop: true);
                        }
                        else
                        {
                            temp = TraverseTreePetrinet(node.RightLeaf, temp, relayedOutgoingPlace: tempLoopEntrancePlace);
                            if (tempLoopExitPlace != null)
                            {
                                temp = tempLoopExitPlace;
                            }
                        }
                    }
                    return(temp);
                }
            }
            else if (node.Operation.Equals(OperationsEnum.isParallel))
            {
                Transition ANDSplit = new Transition("AND-Split");
                ANDSplit.AddIncomingPlace(relayedPlace);
                IMPetriNet.Transitions.Add(ANDSplit);

                Place NewPlaceLeft  = new Place();
                Place NewPlaceRight = new Place();

                IMPetriNet.Places.Add(NewPlaceLeft);
                IMPetriNet.Places.Add(NewPlaceRight);

                ANDSplit.AddOutgoingPlace(NewPlaceLeft);
                ANDSplit.AddOutgoingPlace(NewPlaceRight);

                Transition ANDJoin = new Transition("AND-Join");
                Place      AndJoinOutgoingPlace = new Place();
                ANDJoin.AddOutgoingPlace(AndJoinOutgoingPlace);
                IMPetriNet.Places.Add(AndJoinOutgoingPlace);
                IMPetriNet.Transitions.Add(ANDJoin);

                if (node.LeftLeaf != null)
                {
                    Place temp = TraverseTreePetrinet(node.LeftLeaf, relayedPlace, relayedIncomingPlace: NewPlaceLeft);
                    ANDJoin.AddIncomingPlace(temp);

                    if (node.RightLeaf != null)
                    {
                        temp = TraverseTreePetrinet(node.RightLeaf, NewPlaceRight);
                        ANDJoin.AddIncomingPlace(temp);
                    }
                    return(AndJoinOutgoingPlace);
                }
            }
            else
            {
                throw new Exception("Something in the process tree is wrong.");
            }

            return(relayedPlace);
        }
        /// <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>
        /// Draws the transition with the incoming and outgoing places.
        /// </summary>
        /// <param name="node">Node that will be drawn</param>
        /// <param name="relayed">Relayed place. It will be the incoming place of the transition</param>
        /// <param name="overwriteOutgoingPlace">optional place that will be overwrite the outgoingplace</param>
        /// <param name="overwriteIncomingPlace">optional place that will be overwrite the Incomingplace</param>
        /// <returns>Outgoing Place of the drawn Transition</returns>
        /// <author>Thomas Meents</author>
        private Place DrawLeafPetrinet(InductiveMinerTreeNode node, Place relayed, Place overwriteOutgoingPlace = null, Place overwriteIncomingPlace = null)
        {
            if (!node.Operation.Equals(OperationsEnum.isLeaf))
                throw new Exception("Only leafs can be drawn.");

            Place outgoing = new Place();
            IMPetriNet.Places.Add(outgoing);

            if (overwriteIncomingPlace != null)
                relayed = overwriteIncomingPlace;

            Transition transition = new Transition(node.Event.Name) { IsDrawn = false };
            transition.AddIncomingPlace(relayed);
            transition.AddOutgoingPlace(outgoing);
            if (overwriteOutgoingPlace != null)
            {
                transition.OutgoingPlaces.Remove(outgoing);
                transition.OutgoingPlaces.Add(overwriteOutgoingPlace);
            }
            IMPetriNet.Transitions.Add(transition);

            return outgoing;
        }
        /// <summary>
        /// Recursively moves threw the tree and generates the IMPetrinet
        /// </summary>
        /// <param name="node">actual node</param>
        /// <param name="relayedPlace">Place that the process operator get</param>
        /// <param name="relayedOutgoingPlace">optional place that will be overwrite the outgoingplace</param>
        /// <param name="relayedIncomingPlace">optional place that will be overwrite the incomingplace</param>
        /// <author>Thomas Meents, Bernd Nottbeck</author>
        private Place TraverseTreePetrinet(InductiveMinerTreeNode node, Place relayedPlace, Place relayedOutgoingPlace = null, Place relayedIncomingPlace = null)
        {
            if (node.Operation.Equals(OperationsEnum.isLeaf))
            {
                return DrawLeafPetrinet(node, relayedPlace, overwriteIncomingPlace: relayedIncomingPlace, overwriteOutgoingPlace: relayedOutgoingPlace);
            }

            if (node.Operation.Equals(OperationsEnum.isSequence))
            {
                if (node.LeftLeaf != null)
                {
                    Place temp = TraverseTreePetrinet(node.LeftLeaf, relayedPlace);
                    if (node.RightLeaf != null)
                        temp = TraverseTreePetrinet(node.RightLeaf, temp);
                    return temp;
                }
            }
            else if (node.Operation.Equals(OperationsEnum.isXOR))
            {
                if (node.LeftLeaf != null)
                {
                    Place tempXORExitPlace = TraverseTreePetrinet(node.LeftLeaf, relayedPlace);

                    if (node.RightLeaf == null)
                        return null;

                    Place newPlace = TraverseTreePetrinet(node.RightLeaf, tempXORExitPlace, relayedIncomingPlace: relayedPlace, relayedOutgoingPlace: tempXORExitPlace);

                        if (tempXORExitPlace != null)
                        return tempXORExitPlace;
                    return newPlace;
                }
            }
            else if (node.Operation.Equals(OperationsEnum.isLoop))
            {
                Place tempLoopEntrancePlace = relayedPlace;

                if (node.LeftLeaf != null)
                {
                    Place temp = TraverseTreePetrinet(node.LeftLeaf, relayedPlace);

                    Place tempLoopExitPlace = temp;

                    if (node.RightLeaf != null)
                    {
                        //prevents a Nullpointer-Exception if the first Place is a Loop.
                        if (tempLoopEntrancePlace != IMPetriNet.Places[0])
                        {
                            temp = TraverseTreePetrinet(node.RightLeaf, temp);
                            IMPetriNet.AddTransition("Loop", incomingPlace: temp, outgoingPlace: tempLoopEntrancePlace,
                                isLoop: true);
                        }
                        else
                        {
                            temp = TraverseTreePetrinet(node.RightLeaf, temp, relayedOutgoingPlace: tempLoopEntrancePlace);
                            if (tempLoopExitPlace != null)
                                temp = tempLoopExitPlace;
                        }
                    }
                    return temp;
                }
            }
            else if (node.Operation.Equals(OperationsEnum.isParallel))
            {
                Transition ANDSplit = new Transition("AND-Split");
                ANDSplit.AddIncomingPlace(relayedPlace);
                IMPetriNet.Transitions.Add(ANDSplit);

                Place NewPlaceLeft = new Place();
                Place NewPlaceRight = new Place();

                IMPetriNet.Places.Add(NewPlaceLeft);
                IMPetriNet.Places.Add(NewPlaceRight);

                ANDSplit.AddOutgoingPlace(NewPlaceLeft);
                ANDSplit.AddOutgoingPlace(NewPlaceRight);

                Transition ANDJoin = new Transition("AND-Join");
                Place AndJoinOutgoingPlace = new Place();
                ANDJoin.AddOutgoingPlace(AndJoinOutgoingPlace);
                IMPetriNet.Places.Add(AndJoinOutgoingPlace);
                IMPetriNet.Transitions.Add(ANDJoin);

                if (node.LeftLeaf != null)
                {
                    Place temp = TraverseTreePetrinet(node.LeftLeaf, relayedPlace, relayedIncomingPlace: NewPlaceLeft);
                    ANDJoin.AddIncomingPlace(temp);

                    if (node.RightLeaf != null)
                    {
                        temp = TraverseTreePetrinet(node.RightLeaf, NewPlaceRight);
                        ANDJoin.AddIncomingPlace(temp);
                    }
                    return AndJoinOutgoingPlace;
                }
            }
            else
            {
                throw new Exception("Something in the process tree is wrong.");
            }

            return relayedPlace;
        }