public void GetCaseByNameTest()
        {
            EventLog log         = ExampleData.EventLogExample.OneCaseEventLog();
            Case     examplecase = log.GetCaseByName("ExampleCase");

            Assert.IsTrue(examplecase.Name == "ExampleCase");
        }
示例#2
0
        /// <summary>
        /// Counts the amount of following AND-relations to a given node
        /// </summary>
        /// <param name="node">Current event node</param>
        /// <param name="log">Current event log</param>
        /// <returns>Returns the counted number of and-relations</returns>
        /// <author>Jannik Arndt</author>
        public int CountANDRelations(EventNode node, EventLog log)
        {
            var result = 0;

            for (var index = 0; index < node.ListOfFollowers.Count; index++)
            {
                for (var index2 = index + 1; index2 < node.ListOfFollowers.Count; index2++)
                {
                    try
                    {
                        if (node.ListOfFollowers[index] != null && node.ListOfFollowers[index2] != null)
                        {
                            if (IsAndRelation(node.InnerEvent, node.ListOfFollowers[index].InnerEvent, node.ListOfFollowers[index2].InnerEvent, log))
                            {
                                result++;
                            }
                        }
                    }
                    catch (NullReferenceException)
                    {
                        throw new NullReferenceException("Cannot count AND-relations");
                    }
                }
            }
            return(result);
        }
        /// <summary>
        /// Replays the content of the EventLog on the given PetriNet
        /// </summary>
        /// <param name="petriNet"></param>
        /// <param name="eventLog"></param>
        /// <returns></returns>
        /// <author>Jannik Arndt</author>
        public static TokenReplayResult Replay(PetriNet petriNet, EventLog eventLog)
        {
            var result = new TokenReplayResult { NumberOfCases = eventLog.Cases.Count };

            foreach (var Case in eventLog.Cases)
            {
                var exceptionThrown = false;
                petriNet.ResetTokens();
                foreach (var Event in Case.EventList)
                {
                    try
                    {
                        petriNet.FireTransition(Event.Name);
                    }
                    catch (NullReferenceException)
                    {
                        result.FailedCasesTransitionNotFound.Add(Case);
                        exceptionThrown = true;
                        break;
                    }
                    catch (TransitionNotEnabledException)
                    {
                        result.FailedCasesTransitionNotEnabled.Add(Case);
                        exceptionThrown = true;
                        break;
                    }
                }
                if (!exceptionThrown)
                    result.SuccessfulReplays++;
            }
            return result;
        }
        public void EventLogConstructorTest()
        {
            string eventLogName = "EventLog1";

            EventLog el = new EventLog(name: eventLogName);

            Assert.IsNotNull(el);
        }
示例#5
0
 public Field()
 {
     EventLog = new EventLog();
     DimensionContent1 = new DimensionContent();
     DimensionContent2 = new DimensionContent();
     AdditionalFiltersList = new List<SelectedDimension>();
     ResetInformation();
 }
        private EventLog createEventLogFrom(string sourceFile)
        {
            //The Method should return a list with EventLogs!

            EventLog eventLog = new EventLog(Path.GetFileName(sourceFile));
            Case caseFound = new Case();
            Event eventFound = new Event();

            String theActualElement = "";

            XmlTextReader reader = new XmlTextReader(sourceFile);
            while (reader.Read())
            {
                switch (reader.NodeType)
                {
                    case XmlNodeType.Element: // The node is an element.
                        theActualElement = reader.Name.ToLower();

                        if (reader.Name.ToLower().Equals("processinstance"))
                        {
                            //A new Case starts
                            caseFound = new Case(reader.GetAttribute("id"));
                        }
                        else if (reader.Name.ToLower().Equals("audittrailentry"))
                        {
                            //A new transition starts
                            eventFound = new Event();
                        }

                        break;
                    case XmlNodeType.Text: //Display the text in each element.
                        if (theActualElement.Equals("workflowmodelelement"))
                        {
                            eventFound.Name = reader.Value;
                        }
                        else if (theActualElement.Equals("timestamp"))
                        {
                            eventFound.Information.Add("TIMESTAMP", reader.Value);
                        }
                        break;
                    case XmlNodeType.EndElement: //Display the end of the element.
                        if (reader.Name.ToLower().Equals("processinstance"))
                        {
                            //The case ends in the mxml file and the case must put to the eventlog
                            eventLog.Cases.Add(caseFound);
                        }
                        else if (reader.Name.ToLower().Equals("audittrailentry"))
                        {
                            //The transition ends here
                            caseFound.EventList.Add(eventFound);
                        }

                        break;
                }
            }

            return eventLog;
        }
        /// <summary>
        /// The method create a Footprint for an Eventlog
        /// </summary>
        /// <param name="eventLog">EventLog</param>
        /// <returns>Returns a ComparingFootprintMatrix</returns>
        /// <autor>Andrej Albrecht</autor>
        public static ComparingFootprint CreateFootprint(EventLog eventLog)
        {
            List<ComparingFootprint> footprintList = new List<ComparingFootprint>();

            foreach (Case Case in eventLog.Cases)
                footprintList.Add(CreateFootprint(Case, eventLog.Cases));

            return MergeFootprints(footprintList);
        }
        public void EventFollowsEventTest()
        {
            EventLog log    = ExampleData.EventLogExample.OneCaseEventLog();
            Event    first  = new Event();
            Event    second = new Event();

            foreach (Case cases in log.Cases)
            {
                first  = cases.EventList.First();
                second = cases.EventList.Last();
                break;
            }
            Assert.IsTrue(log.EventFollowsEvent(first, second) == 1, "Count: " + log.EventFollowsEvent(first, second));
        }
示例#9
0
        /// <summary>
        /// Goes through the dependency-graph and creates a petrinet.
        /// </summary>
        /// <param name="dependencyGraph">An EventNode from CreateDependencyGraph()</param>
        /// <param name="eventLog">The EventLog to calculate AND and XOR-relations</param>
        /// <param name="name">The name of the new PetriNet</param>
        /// <returns>A complete petrinet</returns>
        /// <author>Jannik Arndt, Bernhard Bruns</author>
        public PetriNet CreatePetriNetFromDependencyGraph(EventNode dependencyGraph, EventLog eventLog, string name)
        {
            var petriNet = new PetriNet(name);

            // 1. first event
            var startingPlace = petriNet.AddPlace("", 1);
            var firstEvent    = petriNet.AddTransition(dependencyGraph.InnerEvent.Name, incomingPlace: startingPlace);

            // 2. Go through the net and turn Nodes into Places and Transitions, with parallel structures
            HandleNodesAndCloseParallelisms(firstEvent, dependencyGraph, eventLog, petriNet);

            // 3. handle loops
            petriNet = HandleLoops(eventLog, petriNet);

            return(petriNet);
        }
示例#10
0
        /// <summary>
        /// Calculates the adjacency of two events in a given EventLog. Called by CreateAdjacencyMatrix()
        /// </summary>
        /// <param name="event1">First Event</param>
        /// <param name="event2">Second Event</param>
        /// <param name="log">The EventLog to be searched</param>
        /// <returns>The adjacency of two events in an eventlog</returns>
        /// <author>Jannik Arndt</author>
        public double GetAdjacency(Event event1, Event event2, EventLog log)
        {
            if (event1 == null)
            {
                throw new ArgumentNullException("event1", "The given arguments are not valid");
            }
            if (event2 == null)
            {
                throw new ArgumentNullException("event2", "The given arguments are not valid");
            }
            if (log == null)
            {
                throw new ArgumentNullException("log", "The given arguments are not valid");
            }

            var event1ToEvent2 = log.EventFollowsEvent(event1, event2);
            var event2ToEvent1 = log.EventFollowsEvent(event2, event1);

            return(Convert.ToDouble(event1ToEvent2 - event2ToEvent1) / Convert.ToDouble(event1ToEvent2 + event2ToEvent1 + 1));
        }
        /// <summary>
        /// This method creates an event log with one case.
        /// </summary>
        /// <autor>Andrej Albrecht, Markus Holznagel</autor>
        public static EventLog OneCaseEventLogSwitchTheMiddle()
        {
            //Create case
            Case ca = new Case();
            ca.CreateEvent("A");
            ca.CreateEvent("C");
            ca.CreateEvent("B");
            ca.CreateEvent("D");

            //Create event log
            EventLog eventLog = new EventLog();

            return eventLog;
        }
        /// <summary>
        /// Has a corresponding PetriNetExample: (1) -> [One] -> (2) -> [Two] -> (3)-> [Three] -> (4)-> [Four] -> (5)-> [Five] -> (6)
        /// </summary>
        /// <author>Jannik Arndt</author>
        public static EventLog OneTwoThreeFourFive()
        {
            var eventList = new List<Event>
            {
                new Event("One"),
                new Event("Two"),
                new Event("Three"),
                new Event("Four"),
                new Event("Five")
            };

            var caseList = new List<Case>
            {
                new Case("Case1", eventList),
                new Case("Case2", eventList),
                new Case("Case3", eventList),
                new Case("Case4", eventList),
                new Case("Case5", eventList)
            };

            var eventLog = new EventLog {Cases = caseList};

            return eventLog;
        }
        public void CreateFootprintFromEventLogTest1()
        {
            //create Case1
            Case ca = new Case();
            ca.CreateEvent("A");
            ca.CreateEvent("B");
            ca.CreateEvent("C");
            ca.CreateEvent("D");

            //create Case2
            Case ca2 = new Case();
            ca2.CreateEvent("AA");
            ca2.CreateEvent("CC");
            ca2.CreateEvent("BB");
            ca2.CreateEvent("DD");

            //create Case3
            Case ca3 = new Case();
            ca2.CreateEvent("A");
            ca2.CreateEvent("CC");
            ca2.CreateEvent("B");
            ca2.CreateEvent("ZZZ");

            EventLog eventLog = new EventLog();
            eventLog.Cases.Add(ca);
            eventLog.Cases.Add(ca2);
            eventLog.Cases.Add(ca3);

            ComparingFootprint footResult = ComparingFootprintAlgorithm.CreateFootprint(eventLog);

            List<String> headerNames = footResult.HeaderWithEventNames;

            int i = 0;
            foreach (String hName in headerNames)
            {
                if (hName.Equals("A"))
                {
                    i++;
                }
                else if (hName.Equals("B"))
                {
                    i++;
                }
                else if (hName.Equals("C"))
                {
                    i++;
                }
                else if (hName.Equals("D"))
                {
                    i++;
                }
                else if (hName.Equals("AA"))
                {
                    i++;
                }
                else if (hName.Equals("BB"))
                {
                    i++;
                }
                else if (hName.Equals("CC"))
                {
                    i++;
                }
                else if (hName.Equals("DD"))
                {
                    i++;
                }
                else if (hName.Equals("ZZZ"))
                {
                    i++;
                }
                else
                {
                    Assert.Fail();
                }
            }

            if (i != 9 || 9 != headerNames.Count || i != headerNames.Count)
            {
                Assert.Fail();
            }
        }
        /// <summary>
        /// This method creates an event log for recursive parallelisms.
        /// </summary>
        /// <autor>Markus Holznagel</autor>
        public static EventLog EventLogForRecursiveParallelisms()
        {
            // Create Case 1
            Case ca1 = new Case();
            ca1.CreateEvent("A");
            ca1.CreateEvent("B");
            ca1.CreateEvent("C");
            ca1.CreateEvent("D");
            ca1.CreateEvent("F");
            ca1.CreateEvent("H");
            ca1.CreateEvent("J");
            ca1.CreateEvent("L");
            ca1.CreateEvent("M");
            ca1.CreateEvent("N");

            // Create Case 2
            Case ca2 = new Case();
            ca2.CreateEvent("A");
            ca2.CreateEvent("B");
            ca2.CreateEvent("C");
            ca2.CreateEvent("D");
            ca2.CreateEvent("F");
            ca2.CreateEvent("H");
            ca2.CreateEvent("K");
            ca2.CreateEvent("L");
            ca2.CreateEvent("M");
            ca2.CreateEvent("N");

            // Create Case 3
            Case ca3 = new Case();
            ca3.CreateEvent("A");
            ca3.CreateEvent("B");
            ca3.CreateEvent("C");
            ca3.CreateEvent("D");
            ca3.CreateEvent("F");
            ca3.CreateEvent("I");
            ca3.CreateEvent("J");
            ca3.CreateEvent("L");
            ca3.CreateEvent("M");
            ca3.CreateEvent("N");

            // Create Case 4
            Case ca4 = new Case();
            ca4.CreateEvent("A");
            ca4.CreateEvent("B");
            ca4.CreateEvent("C");
            ca4.CreateEvent("D");
            ca4.CreateEvent("F");
            ca4.CreateEvent("I");
            ca4.CreateEvent("K");
            ca4.CreateEvent("L");
            ca4.CreateEvent("M");
            ca4.CreateEvent("N");

            // Create Case 5
            Case ca5 = new Case();
            ca5.CreateEvent("A");
            ca5.CreateEvent("B");
            ca5.CreateEvent("C");
            ca5.CreateEvent("D");
            ca5.CreateEvent("G");
            ca5.CreateEvent("H");
            ca5.CreateEvent("J");
            ca5.CreateEvent("L");
            ca5.CreateEvent("M");
            ca5.CreateEvent("N");

            // Create Case 6
            Case ca6 = new Case();
            ca6.CreateEvent("A");
            ca6.CreateEvent("B");
            ca6.CreateEvent("C");
            ca6.CreateEvent("D");
            ca6.CreateEvent("G");
            ca6.CreateEvent("H");
            ca6.CreateEvent("K");
            ca6.CreateEvent("L");
            ca6.CreateEvent("M");
            ca6.CreateEvent("N");

            // Create Case 7
            Case ca7 = new Case();
            ca7.CreateEvent("A");
            ca7.CreateEvent("B");
            ca7.CreateEvent("C");
            ca7.CreateEvent("D");
            ca7.CreateEvent("G");
            ca7.CreateEvent("I");
            ca7.CreateEvent("J");
            ca7.CreateEvent("L");
            ca7.CreateEvent("M");
            ca7.CreateEvent("N");

            // Create Case 8
            Case ca8 = new Case();
            ca8.CreateEvent("A");
            ca8.CreateEvent("B");
            ca8.CreateEvent("C");
            ca8.CreateEvent("D");
            ca8.CreateEvent("G");
            ca8.CreateEvent("I");
            ca8.CreateEvent("K");
            ca8.CreateEvent("L");
            ca8.CreateEvent("M");
            ca8.CreateEvent("N");

            // Create Case 9
            Case ca9 = new Case();
            ca9.CreateEvent("A");
            ca9.CreateEvent("B");
            ca9.CreateEvent("C");
            ca9.CreateEvent("E");
            ca9.CreateEvent("F");
            ca9.CreateEvent("H");
            ca9.CreateEvent("J");
            ca9.CreateEvent("L");
            ca9.CreateEvent("M");
            ca9.CreateEvent("N");

            // Create Case 10
            Case ca10 = new Case();
            ca10.CreateEvent("A");
            ca10.CreateEvent("B");
            ca10.CreateEvent("C");
            ca10.CreateEvent("E");
            ca10.CreateEvent("F");
            ca10.CreateEvent("H");
            ca10.CreateEvent("K");
            ca10.CreateEvent("L");
            ca10.CreateEvent("M");
            ca10.CreateEvent("N");

            // Create Case 11
            Case ca11 = new Case();
            ca11.CreateEvent("A");
            ca11.CreateEvent("B");
            ca11.CreateEvent("C");
            ca11.CreateEvent("E");
            ca11.CreateEvent("F");
            ca11.CreateEvent("I");
            ca11.CreateEvent("J");
            ca11.CreateEvent("L");
            ca11.CreateEvent("M");
            ca11.CreateEvent("N");

            // Create Case 12
            Case ca12 = new Case();
            ca12.CreateEvent("A");
            ca12.CreateEvent("B");
            ca12.CreateEvent("C");
            ca12.CreateEvent("E");
            ca12.CreateEvent("F");
            ca12.CreateEvent("I");
            ca12.CreateEvent("K");
            ca12.CreateEvent("L");
            ca12.CreateEvent("M");
            ca12.CreateEvent("N");

            // Create Case 13
            Case ca13 = new Case();
            ca13.CreateEvent("A");
            ca13.CreateEvent("B");
            ca13.CreateEvent("C");
            ca13.CreateEvent("E");
            ca13.CreateEvent("G");
            ca13.CreateEvent("H");
            ca13.CreateEvent("J");
            ca13.CreateEvent("L");
            ca13.CreateEvent("M");
            ca13.CreateEvent("N");

            // Create Case 14
            Case ca14 = new Case();
            ca14.CreateEvent("A");
            ca14.CreateEvent("B");
            ca14.CreateEvent("C");
            ca14.CreateEvent("E");
            ca14.CreateEvent("G");
            ca14.CreateEvent("H");
            ca14.CreateEvent("K");
            ca14.CreateEvent("L");
            ca14.CreateEvent("M");
            ca14.CreateEvent("N");

            // Create Case 15
            Case ca15 = new Case();
            ca15.CreateEvent("A");
            ca15.CreateEvent("B");
            ca15.CreateEvent("C");
            ca15.CreateEvent("E");
            ca15.CreateEvent("G");
            ca15.CreateEvent("I");
            ca15.CreateEvent("J");
            ca15.CreateEvent("L");
            ca15.CreateEvent("M");
            ca15.CreateEvent("N");

            // Create Case 16
            Case ca16 = new Case();
            ca16.CreateEvent("A");
            ca16.CreateEvent("B");
            ca16.CreateEvent("C");
            ca16.CreateEvent("E");
            ca16.CreateEvent("G");
            ca16.CreateEvent("I");
            ca16.CreateEvent("K");
            ca16.CreateEvent("L");
            ca16.CreateEvent("M");
            ca16.CreateEvent("N");

            // Create event log
            EventLog eventLog = new EventLog();
            eventLog.Cases.Add(ca1);
            eventLog.Cases.Add(ca2);
            eventLog.Cases.Add(ca3);
            eventLog.Cases.Add(ca4);
            eventLog.Cases.Add(ca5);
            eventLog.Cases.Add(ca6);
            eventLog.Cases.Add(ca7);
            eventLog.Cases.Add(ca8);
            eventLog.Cases.Add(ca9);
            eventLog.Cases.Add(ca10);
            eventLog.Cases.Add(ca11);
            eventLog.Cases.Add(ca12);
            eventLog.Cases.Add(ca13);
            eventLog.Cases.Add(ca14);
            eventLog.Cases.Add(ca15);
            eventLog.Cases.Add(ca16);

            return eventLog;
        }
 /// <summary>
 /// Calculates whether b and c (both followers of a) are in an XOR-relation.
 /// </summary>
 /// <param name="a">First event</param>
 /// <param name="b">Second event</param>
 /// <param name="c">Third event</param>
 /// <param name="log">The current event log</param>
 /// <returns></returns>
 /// <author>Jannik Arndt</author>
 public bool IsXorRelation(Event a, Event b, Event c, EventLog log)
 {
     return !IsAndRelation(a, b, c, log);
 }
        public void EventLogConstructorTest()
        {
            string eventLogName = "EventLog1";

            EventLog el = new EventLog(name: eventLogName);

            Assert.IsNotNull(el);
        }
        /// <summary>
        /// Find loops in the eventlog and add them to the petrinet
        /// </summary>
        /// <param name="eventLog">The eventlog that is searched for loops</param>
        /// <param name="petriNet">The net the loops are added to</param>
        /// <returns>A petrinet with added loops</returns>
        /// <author>Jannik Arndt</author>
        public PetriNet HandleLoops(EventLog eventLog, PetriNet petriNet)
        {
            var loopedActivities = FindLoopingActivities(eventLog);

            foreach (var activity in loopedActivities)
                petriNet.AddLoop(activity);

            return petriNet;
        }
        /// <summary>
        /// A recursive function to call the next level of HandleNode. Also closes open XORs and ANDs right away.
        /// </summary>
        /// <param name="trans"></param>
        /// <param name="node"></param>
        /// <param name="log"></param>
        /// <param name="petriNet"></param>
        /// <author>Jannik Arndt</author>
        public void HandleNodesAndCloseParallelisms(Transition trans, EventNode node, EventLog log, PetriNet petriNet)
        {
            var transitions = HandleNode(trans, node, log, petriNet);
            if (transitions == null)
                return;

            foreach (var transition in transitions)
                foreach (var eventNode in node.ListOfFollowers)
                    if (transition.Name == eventNode.InnerEvent.Name || transition.IsANDJoin)
                        HandleNodesAndCloseParallelisms(transition, eventNode, log, petriNet);
        }
示例#19
0
        /// <summary>
        /// Calculates whether b and c (both followers of a) are in an AND-relation.
        /// </summary>
        /// <param name="a">Event a</param>
        /// <param name="b">Event b</param>
        /// <param name="c">Event c</param>
        /// <param name="log">The current event log</param>
        /// <returns>Returns a result bigger than 0.1</returns>
        /// <author>Jannik Arndt</author>
        public bool IsAndRelation(Event a, Event b, Event c, EventLog log)
        {
            var result = Convert.ToDouble(log.EventFollowsEvent(b, c) + log.EventFollowsEvent(c, b)) / Convert.ToDouble(log.EventFollowsEvent(a, b) + log.EventFollowsEvent(a, c) + 1);

            return(result > 0.1);
        }
示例#20
0
 /// <summary>
 /// Calculates whether b and c (both followers of a) are in an XOR-relation.
 /// </summary>
 /// <param name="a">First event</param>
 /// <param name="b">Second event</param>
 /// <param name="c">Third event</param>
 /// <param name="log">The current event log</param>
 /// <returns></returns>
 /// <author>Jannik Arndt</author>
 public bool IsXorRelation(Event a, Event b, Event c, EventLog log)
 {
     return(!IsAndRelation(a, b, c, log));
 }
示例#21
0
        /// <summary>
        /// A recursive function to call the next level of HandleNode. Also closes open XORs and ANDs right away.
        /// </summary>
        /// <param name="trans"></param>
        /// <param name="node"></param>
        /// <param name="log"></param>
        /// <param name="petriNet"></param>
        /// <author>Jannik Arndt</author>
        public void HandleNodesAndCloseParallelisms(Transition trans, EventNode node, EventLog log, PetriNet petriNet)
        {
            var transitions = HandleNode(trans, node, log, petriNet);

            if (transitions == null)
            {
                return;
            }

            foreach (var transition in transitions)
            {
                foreach (var eventNode in node.ListOfFollowers)
                {
                    if (transition.Name == eventNode.InnerEvent.Name || transition.IsANDJoin)
                    {
                        HandleNodesAndCloseParallelisms(transition, eventNode, log, petriNet);
                    }
                }
            }
        }
        public void CountEventsTest()
        {
            EventLog log = ExampleData.EventLogExample.OneCaseEventLogWithFourOrderedEvents();

            Assert.IsTrue(log.Cases.Count.Equals(log.CountEvents()));
        }
        public void CheckCorrectFitnessBetweenEventLogAndPetrinetTest1()
        {
            //
            //EventLog
            //
            //create Case1
            Case ca1 = new Case();
            ca1.CreateEvent("A");
            ca1.CreateEvent("C");
            ca1.CreateEvent("D");
            ca1.CreateEvent("E");
            ca1.CreateEvent("H");

            //create Case2
            Case ca2 = new Case();
            ca2.CreateEvent("A");
            ca2.CreateEvent("B");
            ca2.CreateEvent("D");
            ca2.CreateEvent("E");
            ca2.CreateEvent("G");

            //create Case3
            Case ca3 = new Case();
            ca3.CreateEvent("A");
            ca3.CreateEvent("D");
            ca3.CreateEvent("C");
            ca3.CreateEvent("E");
            ca3.CreateEvent("H");

            //create Case4
            Case ca4 = new Case();
            ca4.CreateEvent("A");
            ca4.CreateEvent("B");
            ca4.CreateEvent("D");
            ca4.CreateEvent("E");
            ca4.CreateEvent("H");

            //create Case5
            Case ca5 = new Case();
            ca5.CreateEvent("A");
            ca5.CreateEvent("C");
            ca5.CreateEvent("D");
            ca5.CreateEvent("E");
            ca5.CreateEvent("G");

            //create Case6
            Case ca6 = new Case();
            ca6.CreateEvent("A");
            ca6.CreateEvent("D");
            ca6.CreateEvent("C");
            ca6.CreateEvent("E");
            ca6.CreateEvent("G");

            //create Case7
            Case ca7 = new Case();
            ca7.CreateEvent("A");
            ca7.CreateEvent("D");
            ca7.CreateEvent("B");
            ca7.CreateEvent("E");
            ca7.CreateEvent("H");

            //create Case8
            Case ca8 = new Case();
            ca8.CreateEvent("A");
            ca8.CreateEvent("C");
            ca8.CreateEvent("D");
            ca8.CreateEvent("E");
            ca8.CreateEvent("F");
            ca8.CreateEvent("D");
            ca8.CreateEvent("B");
            ca8.CreateEvent("E");
            ca8.CreateEvent("H");

            //create Case9
            Case ca9 = new Case();
            ca9.CreateEvent("A");
            ca9.CreateEvent("D");
            ca9.CreateEvent("B");
            ca9.CreateEvent("E");
            ca9.CreateEvent("G");

            //create Case10
            Case ca10 = new Case();
            ca10.CreateEvent("A");
            ca10.CreateEvent("C");
            ca10.CreateEvent("D");
            ca10.CreateEvent("E");
            ca10.CreateEvent("F");
            ca10.CreateEvent("B");
            ca10.CreateEvent("D");
            ca10.CreateEvent("E");
            ca10.CreateEvent("H");

            //create Case11
            Case ca11 = new Case();
            ca11.CreateEvent("A");
            ca11.CreateEvent("C");
            ca11.CreateEvent("D");
            ca11.CreateEvent("E");
            ca11.CreateEvent("F");
            ca11.CreateEvent("B");
            ca11.CreateEvent("D");
            ca11.CreateEvent("E");
            ca11.CreateEvent("G");

            //create Case12
            Case ca12 = new Case();
            ca12.CreateEvent("A");
            ca12.CreateEvent("C");
            ca12.CreateEvent("D");
            ca12.CreateEvent("E");
            ca12.CreateEvent("F");
            ca12.CreateEvent("D");
            ca12.CreateEvent("B");
            ca12.CreateEvent("E");
            ca12.CreateEvent("G");

            //create Case13
            Case ca13 = new Case();
            ca13.CreateEvent("A");
            ca13.CreateEvent("D");
            ca13.CreateEvent("C");
            ca13.CreateEvent("E");
            ca13.CreateEvent("F");
            ca13.CreateEvent("C");
            ca13.CreateEvent("D");
            ca13.CreateEvent("E");
            ca13.CreateEvent("H");

            //create Case14
            Case ca14 = new Case();
            ca14.CreateEvent("A");
            ca14.CreateEvent("D");
            ca14.CreateEvent("C");
            ca14.CreateEvent("E");
            ca14.CreateEvent("F");
            ca14.CreateEvent("D");
            ca14.CreateEvent("B");
            ca14.CreateEvent("E");
            ca14.CreateEvent("H");

            //create Case15
            Case ca15 = new Case();
            ca15.CreateEvent("A");
            ca15.CreateEvent("D");
            ca15.CreateEvent("C");
            ca15.CreateEvent("E");
            ca15.CreateEvent("F");
            ca15.CreateEvent("B");
            ca15.CreateEvent("D");
            ca15.CreateEvent("E");
            ca15.CreateEvent("G");

            //create Case16
            Case ca16 = new Case();
            ca16.CreateEvent("A");
            ca16.CreateEvent("C");
            ca16.CreateEvent("D");
            ca16.CreateEvent("E");
            ca16.CreateEvent("F");
            ca16.CreateEvent("B");
            ca16.CreateEvent("D");
            ca16.CreateEvent("E");
            ca16.CreateEvent("F");
            ca16.CreateEvent("D");
            ca16.CreateEvent("B");
            ca16.CreateEvent("E");
            ca16.CreateEvent("G");

            //create Case17
            Case ca17 = new Case();
            ca17.CreateEvent("A");
            ca17.CreateEvent("D");
            ca17.CreateEvent("C");
            ca17.CreateEvent("E");
            ca17.CreateEvent("F");
            ca17.CreateEvent("D");
            ca17.CreateEvent("B");
            ca17.CreateEvent("E");
            ca17.CreateEvent("G");

            //create Case18
            Case ca18 = new Case();
            ca18.CreateEvent("A");
            ca18.CreateEvent("D");
            ca18.CreateEvent("C");
            ca18.CreateEvent("E");
            ca18.CreateEvent("F");
            ca18.CreateEvent("B");
            ca18.CreateEvent("D");
            ca18.CreateEvent("E");
            ca18.CreateEvent("F");
            ca18.CreateEvent("B");
            ca18.CreateEvent("D");
            ca18.CreateEvent("E");
            ca18.CreateEvent("G");

            //create Case19
            Case ca19 = new Case();
            ca19.CreateEvent("A");
            ca19.CreateEvent("D");
            ca19.CreateEvent("C");
            ca19.CreateEvent("E");
            ca19.CreateEvent("F");
            ca19.CreateEvent("D");
            ca19.CreateEvent("B");
            ca19.CreateEvent("E");
            ca19.CreateEvent("F");
            ca19.CreateEvent("B");
            ca19.CreateEvent("D");
            ca19.CreateEvent("E");
            ca19.CreateEvent("H");

            //create Case20
            Case ca20 = new Case();
            ca20.CreateEvent("A");
            ca20.CreateEvent("D");
            ca20.CreateEvent("B");
            ca20.CreateEvent("E");
            ca20.CreateEvent("F");
            ca20.CreateEvent("B");
            ca20.CreateEvent("D");
            ca20.CreateEvent("E");
            ca20.CreateEvent("F");
            ca20.CreateEvent("D");
            ca20.CreateEvent("B");
            ca20.CreateEvent("E");
            ca20.CreateEvent("G");

            //create Case21
            Case ca21 = new Case();
            ca21.CreateEvent("A");
            ca21.CreateEvent("D");
            ca21.CreateEvent("C");
            ca21.CreateEvent("E");
            ca21.CreateEvent("F");
            ca21.CreateEvent("D");
            ca21.CreateEvent("B");
            ca21.CreateEvent("E");
            ca21.CreateEvent("F");
            ca21.CreateEvent("C");
            ca21.CreateEvent("D");
            ca21.CreateEvent("E");
            ca21.CreateEvent("F");
            ca21.CreateEvent("D");
            ca21.CreateEvent("B");
            ca21.CreateEvent("E");
            ca21.CreateEvent("G");

            //create Event Log
            EventLog eventLog = new EventLog();
            eventLog.Cases.Add(ca1);
            eventLog.Cases.Add(ca2);
            eventLog.Cases.Add(ca3);
            eventLog.Cases.Add(ca4);
            eventLog.Cases.Add(ca5);
            eventLog.Cases.Add(ca6);
            eventLog.Cases.Add(ca7);
            eventLog.Cases.Add(ca8);
            eventLog.Cases.Add(ca9);
            eventLog.Cases.Add(ca10);
            eventLog.Cases.Add(ca11);
            eventLog.Cases.Add(ca12);
            eventLog.Cases.Add(ca13);
            eventLog.Cases.Add(ca14);
            eventLog.Cases.Add(ca15);
            eventLog.Cases.Add(ca16);
            eventLog.Cases.Add(ca17);
            eventLog.Cases.Add(ca18);
            eventLog.Cases.Add(ca19);
            eventLog.Cases.Add(ca20);
            eventLog.Cases.Add(ca21);

            //
            //PetriNet
            //
            PetriNet petriNet = new PetriNet("Petri-Net Name");

            Place pStart = new Place("Place Start", 0);
            Place pC1 = new Place("c1", 0);
            Place pC2 = new Place("c2", 0);
            Place pC3 = new Place("c3", 0);
            Place pC4 = new Place("c4", 0);
            Place pC5 = new Place("c5", 0);
            Place pEnd = new Place("Place End", 0);

            Transition tA = new Transition("A");
            Transition tB = new Transition("B");
            Transition tC = new Transition("C");
            Transition tD = new Transition("D");
            Transition tE = new Transition("E");
            Transition tF = new Transition("F");
            Transition tG = new Transition("G");
            Transition tH = new Transition("H");

            tG.AddOutgoingPlace(pEnd);
            tG.AddIncomingPlace(pC5);

            tH.AddOutgoingPlace(pEnd);
            tH.AddIncomingPlace(pC5);

            tE.AddIncomingPlace(pC3);
            tE.AddIncomingPlace(pC4);
            tE.AddOutgoingPlace(pC5);

            pC3.AppendIncomingTransition(tB);
            pC3.AppendIncomingTransition(tC);
            pC3.AppendOutgoingTransition(tE);

            pC4.AppendOutgoingTransition(tE);

            tB.AddIncomingPlace(pC1);
            tB.AddOutgoingPlace(pC3);

            tC.AddIncomingPlace(pC1);
            tC.AddOutgoingPlace(pC3);

            tD.AddIncomingPlace(pC2);
            tD.AddOutgoingPlace(pC4);

            pC1.AppendIncomingTransition(tA);
            pC1.AppendOutgoingTransition(tB);
            pC1.AppendOutgoingTransition(tC);

            pC2.AppendIncomingTransition(tA);
            pC2.AppendOutgoingTransition(tD);

            tF.AddIncomingPlace(pC5);
            tF.AddOutgoingPlace(pC1);
            tF.AddOutgoingPlace(pC2);

            //
            tA.AddIncomingPlace(pStart);
            tA.AddOutgoingPlace(pC1);
            tA.AddOutgoingPlace(pC2);

            pStart.AppendOutgoingTransition(tA);

            pEnd.AppendIncomingTransition(tG);
            pEnd.AppendIncomingTransition(tH);

            ////
            petriNet.Transitions.Add(tA);
            petriNet.Transitions.Add(tB);
            petriNet.Transitions.Add(tC);
            petriNet.Transitions.Add(tD);
            petriNet.Transitions.Add(tE);
            petriNet.Transitions.Add(tF);
            petriNet.Transitions.Add(tG);
            petriNet.Transitions.Add(tH);

            ////
            petriNet.Places.Add(pStart);
            petriNet.Places.Add(pC1);
            petriNet.Places.Add(pC2);
            petriNet.Places.Add(pC3);
            petriNet.Places.Add(pC4);
            petriNet.Places.Add(pC5);
            petriNet.Places.Add(pEnd);

            ComparingFootprintResultMatrix matrix = new ComparingFootprintResultMatrix(ComparingFootprintAlgorithm.CreateFootprint(eventLog), ComparingFootprintAlgorithm.CreateFootprint(petriNet));
            double fitness = ComparingFootprintAlgorithm.CalculateFitness(matrix.GetNumberOfDifferences(), matrix.GetNumberOfOpportunities());

            if (Math.Abs(fitness - 1.0) > 0.0001)
            {
                Assert.Fail("Fitness not correct! (" + fitness + ")");
            }
        }
        /// <summary>
        /// Calculates the adjacency of two events in a given EventLog. Called by CreateAdjacencyMatrix()
        /// </summary>
        /// <param name="event1">First Event</param>
        /// <param name="event2">Second Event</param>
        /// <param name="log">The EventLog to be searched</param>
        /// <returns>The adjacency of two events in an eventlog</returns>
        /// <author>Jannik Arndt</author>
        public double GetAdjacency(Event event1, Event event2, EventLog log)
        {
            if (event1 == null)
                throw new ArgumentNullException("event1", "The given arguments are not valid");
            if (event2 == null)
                throw new ArgumentNullException("event2", "The given arguments are not valid");
            if (log == null)
                throw new ArgumentNullException("log", "The given arguments are not valid");

            var event1ToEvent2 = log.EventFollowsEvent(event1, event2);
            var event2ToEvent1 = log.EventFollowsEvent(event2, event1);
            return Convert.ToDouble(event1ToEvent2 - event2ToEvent1) / Convert.ToDouble(event1ToEvent2 + event2ToEvent1 + 1);
        }
        public void EventLogAddAndGetCaseTest3()
        {
            EventLog el = new EventLog(name: "EventLogName");

            //create Case1
            Case ca = new Case("Case1");

            ca.CreateEvent("A");
            ca.CreateEvent("B");
            ca.CreateEvent("C");
            ca.CreateEvent("D");

            //create Case2
            Case ca2 = new Case("Case2");

            ca2.CreateEvent("AA");
            ca2.CreateEvent("CC");
            ca2.CreateEvent("BB");
            ca2.CreateEvent("DD");

            Case ca3 = new Case("Case3");

            ca3.CreateEvent("AAA");
            ca3.CreateEvent("CCC");
            ca3.CreateEvent("BBB");
            ca3.CreateEvent("DDD");

            el.Cases.Add(ca);
            el.Cases.Add(ca2);
            el.Cases.Add(ca3);


            Case caseGet2    = el.GetCaseByName("Case2");
            int  countEvents = 0;

            foreach (Event e in caseGet2.EventList)
            {
                if (e.Name.Equals("AA") ||
                    e.Name.Equals("BB") ||
                    e.Name.Equals("CC") ||
                    e.Name.Equals("DD"))
                {
                    countEvents++;
                }
                else
                {
                    Assert.Fail("Event not in cases and not in eventlog");
                }
            }

            if (countEvents != 4)
            {
                Assert.Fail("not the right number of cases in the event log countEvents:" + countEvents);
            }

            //
            // Overwrite test:
            //
            Case caNew3 = new Case("Case3");

            caNew3.CreateEvent("NewAAA");
            caNew3.CreateEvent("NewCCC");
            caNew3.CreateEvent("NewBBB");
            caNew3.CreateEvent("NewDDD");

            el.Cases.Add(caNew3);

            Case caseGet3 = el.GetCaseByName("Case3");

            countEvents = 0;
            foreach (Event e in caseGet3.EventList)
            {
                Debug.WriteLine("e.Name:" + e.Name);

                if (e.Name.Equals("AAA") ||
                    e.Name.Equals("CCC") ||
                    e.Name.Equals("BBB") ||
                    e.Name.Equals("DDD"))
                {
                    countEvents++;
                }
                else if (e.Name.Equals("NewAAA") ||
                         e.Name.Equals("NewCCC") ||
                         e.Name.Equals("NewBBB") ||
                         e.Name.Equals("NewDDD"))
                {
                    Assert.Fail("Overwrite test failed");
                }
            }

            if (countEvents != 4)
            {
                Assert.Fail("not the right number of cases in the event log (countEvents:" + countEvents + ")");
            }
        }
        /// <summary>
        /// Depending on the count of followers this adds one (or more) places and their following transitions.
        /// </summary>
        /// <param name="event1"></param>
        /// <param name="node">An event node</param>
        /// <param name="log">The current event log</param>
        /// <param name="petriNet"></param>
        /// <returns>The newly added transitions. This is where you need to continue working.</returns>
        /// <exception cref="NotImplementedException">If there are more than 3 followers in a non-trivial relation.</exception>
        /// <author>Jannik Arndt</author>
        public List<Transition> HandleNode(Transition event1, EventNode node, EventLog log, PetriNet petriNet)
        {
            // Case: No followers
            if (node.ListOfFollowers.Count == 0)
                return new List<Transition>();

            // one or more more followers => count the AND-relations
            var andRelations = CountANDRelations(node, log);

            // Case: All nodes are AND-related
            if (andRelations == node.ListOfFollowers.Count)
                return StartAND(event1, node.ListOfFollowers, petriNet);

            // Case: All nodes are XOR-related
            if (andRelations == 0)
                return StartXOR(event1, node.ListOfFollowers, petriNet);

            // Case: 3 Followers
            if (node.ListOfFollowers.Count == 3)
            {
                var x = node;
                var a = node.ListOfFollowers[0];
                var b = node.ListOfFollowers[1];
                var c = node.ListOfFollowers[2];

                if (andRelations == 2) // XOR-Relations == 1
                {
                    // There are two and-relations and one xor-relation. Find the xor and order the parameters accordingly
                    if (IsXorRelation(x.InnerEvent, b.InnerEvent, c.InnerEvent, log))
                        return StartAand_BxorC(event1, a, b, c, petriNet);
                    if (IsXorRelation(x.InnerEvent, a.InnerEvent, c.InnerEvent, log))
                        return StartAand_BxorC(event1, b, a, c, petriNet);
                    if (IsXorRelation(x.InnerEvent, a.InnerEvent, b.InnerEvent, log))
                        return StartAand_BxorC(event1, c, a, b, petriNet);
                }
                else // XOR-Relations == 2 && AND-Relations == 1
                {
                    // There are two xor-relations and one and-relation. Find the and and order the parameters accordingly
                    if (IsAndRelation(x.InnerEvent, b.InnerEvent, c.InnerEvent, log))
                        return StartAxor_BandC(event1, a, b, c, petriNet);
                    if (IsAndRelation(x.InnerEvent, a.InnerEvent, c.InnerEvent, log))
                        return StartAxor_BandC(event1, b, a, c, petriNet);
                    if (IsAndRelation(x.InnerEvent, a.InnerEvent, b.InnerEvent, log))
                        return StartAxor_BandC(event1, c, a, b, petriNet);
                }
            }
            if (node.ListOfFollowers.Count > 3)
                return StartXOR(event1, node.ListOfFollowers, petriNet);

            // optional transition
            if (node.ListOfFollowers.Count == 2)
                if (log.EventFollowsEvent(node.ListOfFollowers[0].InnerEvent, node.ListOfFollowers[1].InnerEvent) > 0)
                    return StartOptionalTransition(event1, node.ListOfFollowers[0].InnerEvent.Name, node.ListOfFollowers[1].InnerEvent.Name, petriNet);
                else if (log.EventFollowsEvent(node.ListOfFollowers[1].InnerEvent, node.ListOfFollowers[0].InnerEvent) > 0)
                    return StartOptionalTransition(event1, node.ListOfFollowers[1].InnerEvent.Name, node.ListOfFollowers[0].InnerEvent.Name, petriNet);

            return null;
        }
        public void CompareEventLogAndPetriNetTest1()
        {
            //
            //EventLog
            //
            //create Case1
            Case ca1 = new Case();
            ca1.CreateEvent("A");
            ca1.CreateEvent("C");
            ca1.CreateEvent("D");
            ca1.CreateEvent("E");
            ca1.CreateEvent("H");

            //create Case2
            Case ca2 = new Case();
            ca2.CreateEvent("A");
            ca2.CreateEvent("B");
            ca2.CreateEvent("D");
            ca2.CreateEvent("E");
            ca2.CreateEvent("G");

            //create Case3
            Case ca3 = new Case();
            ca3.CreateEvent("A");
            ca3.CreateEvent("D");
            ca3.CreateEvent("C");
            ca3.CreateEvent("E");
            ca3.CreateEvent("H");

            //create Case4
            Case ca4 = new Case();
            ca4.CreateEvent("A");
            ca4.CreateEvent("B");
            ca4.CreateEvent("D");
            ca4.CreateEvent("E");
            ca4.CreateEvent("H");

            //create Case5
            Case ca5 = new Case();
            ca5.CreateEvent("A");
            ca5.CreateEvent("C");
            ca5.CreateEvent("D");
            ca5.CreateEvent("E");
            ca5.CreateEvent("G");

            //create Case6
            Case ca6 = new Case();
            ca6.CreateEvent("A");
            ca6.CreateEvent("D");
            ca6.CreateEvent("C");
            ca6.CreateEvent("E");
            ca6.CreateEvent("G");

            //create Case7
            Case ca7 = new Case();
            ca7.CreateEvent("A");
            ca7.CreateEvent("D");
            ca7.CreateEvent("B");
            ca7.CreateEvent("E");
            ca7.CreateEvent("H");

            //create Case8
            Case ca8 = new Case();
            ca8.CreateEvent("A");
            ca8.CreateEvent("C");
            ca8.CreateEvent("D");
            ca8.CreateEvent("E");
            ca8.CreateEvent("F");
            ca8.CreateEvent("D");
            ca8.CreateEvent("B");
            ca8.CreateEvent("E");
            ca8.CreateEvent("H");

            //create Case9
            Case ca9 = new Case();
            ca9.CreateEvent("A");
            ca9.CreateEvent("D");
            ca9.CreateEvent("B");
            ca9.CreateEvent("E");
            ca9.CreateEvent("G");

            //create Case10
            Case ca10 = new Case();
            ca10.CreateEvent("A");
            ca10.CreateEvent("C");
            ca10.CreateEvent("D");
            ca10.CreateEvent("E");
            ca10.CreateEvent("F");
            ca10.CreateEvent("B");
            ca10.CreateEvent("D");
            ca10.CreateEvent("E");
            ca10.CreateEvent("H");

            //create Case11
            Case ca11 = new Case();
            ca11.CreateEvent("A");
            ca11.CreateEvent("C");
            ca11.CreateEvent("D");
            ca11.CreateEvent("E");
            ca11.CreateEvent("F");
            ca11.CreateEvent("B");
            ca11.CreateEvent("D");
            ca11.CreateEvent("E");
            ca11.CreateEvent("G");

            //create Case12
            Case ca12 = new Case();
            ca12.CreateEvent("A");
            ca12.CreateEvent("C");
            ca12.CreateEvent("D");
            ca12.CreateEvent("E");
            ca12.CreateEvent("F");
            ca12.CreateEvent("D");
            ca12.CreateEvent("B");
            ca12.CreateEvent("E");
            ca12.CreateEvent("G");

            //create Case13
            Case ca13 = new Case();
            ca13.CreateEvent("A");
            ca13.CreateEvent("D");
            ca13.CreateEvent("C");
            ca13.CreateEvent("E");
            ca13.CreateEvent("F");
            ca13.CreateEvent("C");
            ca13.CreateEvent("D");
            ca13.CreateEvent("E");
            ca13.CreateEvent("H");

            //create Case14
            Case ca14 = new Case();
            ca14.CreateEvent("A");
            ca14.CreateEvent("D");
            ca14.CreateEvent("C");
            ca14.CreateEvent("E");
            ca14.CreateEvent("F");
            ca14.CreateEvent("D");
            ca14.CreateEvent("B");
            ca14.CreateEvent("E");
            ca14.CreateEvent("H");

            //create Case15
            Case ca15 = new Case();
            ca15.CreateEvent("A");
            ca15.CreateEvent("D");
            ca15.CreateEvent("C");
            ca15.CreateEvent("E");
            ca15.CreateEvent("F");
            ca15.CreateEvent("B");
            ca15.CreateEvent("D");
            ca15.CreateEvent("E");
            ca15.CreateEvent("G");

            //create Case16
            Case ca16 = new Case();
            ca16.CreateEvent("A");
            ca16.CreateEvent("C");
            ca16.CreateEvent("D");
            ca16.CreateEvent("E");
            ca16.CreateEvent("F");
            ca16.CreateEvent("B");
            ca16.CreateEvent("D");
            ca16.CreateEvent("E");
            ca16.CreateEvent("F");
            ca16.CreateEvent("D");
            ca16.CreateEvent("B");
            ca16.CreateEvent("E");
            ca16.CreateEvent("G");

            //create Case17
            Case ca17 = new Case();
            ca17.CreateEvent("A");
            ca17.CreateEvent("D");
            ca17.CreateEvent("C");
            ca17.CreateEvent("E");
            ca17.CreateEvent("F");
            ca17.CreateEvent("D");
            ca17.CreateEvent("B");
            ca17.CreateEvent("E");
            ca17.CreateEvent("G");

            //create Case18
            Case ca18 = new Case();
            ca18.CreateEvent("A");
            ca18.CreateEvent("D");
            ca18.CreateEvent("C");
            ca18.CreateEvent("E");
            ca18.CreateEvent("F");
            ca18.CreateEvent("B");
            ca18.CreateEvent("D");
            ca18.CreateEvent("E");
            ca18.CreateEvent("F");
            ca18.CreateEvent("B");
            ca18.CreateEvent("D");
            ca18.CreateEvent("E");
            ca18.CreateEvent("G");

            //create Case19
            Case ca19 = new Case();
            ca19.CreateEvent("A");
            ca19.CreateEvent("D");
            ca19.CreateEvent("C");
            ca19.CreateEvent("E");
            ca19.CreateEvent("F");
            ca19.CreateEvent("D");
            ca19.CreateEvent("B");
            ca19.CreateEvent("E");
            ca19.CreateEvent("F");
            ca19.CreateEvent("B");
            ca19.CreateEvent("D");
            ca19.CreateEvent("E");
            ca19.CreateEvent("H");

            //create Case20
            Case ca20 = new Case();
            ca20.CreateEvent("A");
            ca20.CreateEvent("D");
            ca20.CreateEvent("B");
            ca20.CreateEvent("E");
            ca20.CreateEvent("F");
            ca20.CreateEvent("B");
            ca20.CreateEvent("D");
            ca20.CreateEvent("E");
            ca20.CreateEvent("F");
            ca20.CreateEvent("D");
            ca20.CreateEvent("B");
            ca20.CreateEvent("E");
            ca20.CreateEvent("G");

            //create Case21
            Case ca21 = new Case();
            ca21.CreateEvent("A");
            ca21.CreateEvent("D");
            ca21.CreateEvent("C");
            ca21.CreateEvent("E");
            ca21.CreateEvent("F");
            ca21.CreateEvent("D");
            ca21.CreateEvent("B");
            ca21.CreateEvent("E");
            ca21.CreateEvent("F");
            ca21.CreateEvent("C");
            ca21.CreateEvent("D");
            ca21.CreateEvent("E");
            ca21.CreateEvent("F");
            ca21.CreateEvent("D");
            ca21.CreateEvent("B");
            ca21.CreateEvent("E");
            ca21.CreateEvent("G");

            //create Event Log
            EventLog eventLog = new EventLog();
            eventLog.Cases.Add(ca1);
            eventLog.Cases.Add(ca2);
            eventLog.Cases.Add(ca3);
            eventLog.Cases.Add(ca4);
            eventLog.Cases.Add(ca5);
            eventLog.Cases.Add(ca6);
            eventLog.Cases.Add(ca7);
            eventLog.Cases.Add(ca8);
            eventLog.Cases.Add(ca9);
            eventLog.Cases.Add(ca10);
            eventLog.Cases.Add(ca11);
            eventLog.Cases.Add(ca12);
            eventLog.Cases.Add(ca13);
            eventLog.Cases.Add(ca14);
            eventLog.Cases.Add(ca15);
            eventLog.Cases.Add(ca16);
            eventLog.Cases.Add(ca17);
            eventLog.Cases.Add(ca18);
            eventLog.Cases.Add(ca19);
            eventLog.Cases.Add(ca20);
            eventLog.Cases.Add(ca21);

            //
            //PetriNet
            //
            PetriNet petriNet = new PetriNet("Petri-Net Name");

            Place pStart = new Place("Place Start", 0);
            Place pC1 = new Place("c1", 0);
            Place pC2 = new Place("c2", 0);
            Place pC3 = new Place("c3", 0);
            Place pC4 = new Place("c4", 0);
            Place pC5 = new Place("c5", 0);
            Place pEnd = new Place("Place End", 0);

            Transition tA = new Transition("A");
            Transition tB = new Transition("B");
            Transition tC = new Transition("C");
            Transition tD = new Transition("D");
            Transition tE = new Transition("E");
            Transition tF = new Transition("F");
            Transition tG = new Transition("G");
            Transition tH = new Transition("H");

            tG.AddOutgoingPlace(pEnd);
            tG.AddIncomingPlace(pC5);

            tH.AddOutgoingPlace(pEnd);
            tH.AddIncomingPlace(pC5);

            tE.AddIncomingPlace(pC3);
            tE.AddIncomingPlace(pC4);
            tE.AddOutgoingPlace(pC5);

            pC3.AppendIncomingTransition(tB);
            pC3.AppendIncomingTransition(tC);
            pC3.AppendOutgoingTransition(tE);

            pC4.AppendIncomingTransition(tD);
            pC4.AppendOutgoingTransition(tE);

            tB.AddIncomingPlace(pC1);
            tB.AddOutgoingPlace(pC3);

            tC.AddIncomingPlace(pC1);
            tC.AddOutgoingPlace(pC3);

            tD.AddIncomingPlace(pC2);
            tD.AddOutgoingPlace(pC4);

            pC1.AppendIncomingTransition(tA);
            pC1.AppendOutgoingTransition(tB);
            pC1.AppendOutgoingTransition(tC);

            pC2.AppendIncomingTransition(tA);
            pC2.AppendOutgoingTransition(tD);

            tF.AddIncomingPlace(pC5);
            tF.AddOutgoingPlace(pC1);
            tF.AddOutgoingPlace(pC2);

            //
            tA.AddIncomingPlace(pStart);
            tA.AddOutgoingPlace(pC1);
            tA.AddOutgoingPlace(pC2);

            pStart.AppendOutgoingTransition(tA);

            pEnd.AppendIncomingTransition(tG);
            pEnd.AppendIncomingTransition(tH);

            ////
            petriNet.Transitions.Add(tA);
            petriNet.Transitions.Add(tB);
            petriNet.Transitions.Add(tC);
            petriNet.Transitions.Add(tD);
            petriNet.Transitions.Add(tE);
            petriNet.Transitions.Add(tF);
            petriNet.Transitions.Add(tG);
            petriNet.Transitions.Add(tH);

            ////
            petriNet.Places.Add(pStart);
            petriNet.Places.Add(pC1);
            petriNet.Places.Add(pC2);
            petriNet.Places.Add(pC3);
            petriNet.Places.Add(pC4);
            petriNet.Places.Add(pC5);
            petriNet.Places.Add(pEnd);

            ComparingFootprint footprintEventLog = ComparingFootprintAlgorithm.CreateFootprint(eventLog);
            ComparingFootprint footprintPetriNet = ComparingFootprintAlgorithm.CreateFootprint(petriNet);

            ComparingFootprintResultMatrix footprintResultMatrix = new ComparingFootprintResultMatrix(footprintEventLog, footprintPetriNet);

            if (footprintResultMatrix.HeaderWithEventNames.Count != 8)
            {
                Assert.Fail("");
            }

            int y = 0;
            foreach (String headerNameY in footprintResultMatrix.HeaderWithEventNames)
            {
                int x = 0;
                foreach (String headerNameX in footprintResultMatrix.HeaderWithEventNames)
                {
                    ResultCellType resultCellType = footprintResultMatrix.ResultMatrix[y, x];
                    Console.WriteLine("Test headerNameY: " + headerNameY + ", headerNameX: " + headerNameX + " [" + y + "," + x + "].CellType:" + resultCellType);

                    if (!resultCellType.Equals(ResultCellType.NoDifferences))
                    {
                        Assert.Fail("Test headerNameY: " + headerNameY + ", headerNameX: " + headerNameX + " [" + y + "," + x + "].CellType:" + resultCellType);
                    }

                    x++;
                }
                y++;
            }

            //Arrange (Create Footprints)
            ComparingFootprint footPrintEventlog = ComparingFootprintAlgorithm.CreateFootprint(eventLog);
            ComparingFootprint footPrintPetrinet = ComparingFootprintAlgorithm.CreateFootprint(petriNet);
            ComparingFootprintResultMatrix resultFootprint = new ComparingFootprintResultMatrix(footPrintEventlog, footPrintPetrinet);

            // Act (Calculate Fitness)
            double fitnessComparingFootprint = ComparingFootprintAlgorithm.CalculateFitness(resultFootprint.GetNumberOfDifferences(), resultFootprint.GetNumberOfOpportunities());

            if (fitnessComparingFootprint != 1.0)
            {
                // Assert
                Assert.Fail("Fitness not correct! (" + fitnessComparingFootprint + ")");
            }
        }
 /// <summary>
 /// Calculates whether b and c (both followers of a) are in an AND-relation.
 /// </summary>
 /// <param name="a">Event a</param>
 /// <param name="b">Event b</param>
 /// <param name="c">Event c</param>
 /// <param name="log">The current event log</param>
 /// <returns>Returns a result bigger than 0.1</returns>
 /// <author>Jannik Arndt</author>
 public bool IsAndRelation(Event a, Event b, Event c, EventLog log)
 {
     var result = Convert.ToDouble(log.EventFollowsEvent(b, c) + log.EventFollowsEvent(c, b)) / Convert.ToDouble(log.EventFollowsEvent(a, b) + log.EventFollowsEvent(a, c) + 1);
     return result > 0.1;
 }
 public MXMLExporter(EventLog eventLog)
 {
     this.eventLog = eventLog;
 }
        /// <summary>
        /// Go through the eventlog and find all events that occur multiple times in a row
        /// </summary>
        /// <param name="eventLog">Any eventlog</param>
        /// <returns>A HashSet of strings (activity-names)</returns>
        /// <author>Jannik Arndt</author>
        private IEnumerable<string> FindLoopingActivities(EventLog eventLog)
        {
            var loopedActivities = new HashSet<string>();
            var currentActivity = "";

            foreach (var Case in eventLog.Cases)
                foreach (var Event in Case.EventList)
                    // if the current event and the event before have the same name, there is a loop
                    if (Event.Name == currentActivity)
                        loopedActivities.Add(Event.Name);
                    else
                        currentActivity = Event.Name;

            return loopedActivities;
        }
        private string createInsertStatementForMySQLFrom(EventLog eventLog)
        {
            StringBuilder sql = new StringBuilder();
            sql.Append("-- PG MPM Insert Statement\n");
            sql.Append("SET AUTOCOMMIT=0;\n");
            sql.Append("START TRANSACTION;\n");
            sql.Append("\nINSERT INTO `DIM_PROCESS` (`content`, `description`) VALUES ('" + eventLog.Name + "', '" + eventLog.Name + "');\n\n");

            //Insert Time if not exists
            //sql += "\nINSERT INTO `DIM_DATETIME` (`content`, `description`) VALUES (CAST(NOW() AS char), CAST(NOW() AS char));\n\n";
            sql.Append("\nINSERT INTO `DIM_TIME_DAY` (`content`, `description`) VALUES ('2000-01-01 00:00:00', '2000-01-01 00:00:00');\n\n");

            sql.Append("\nINSERT INTO `FACT` (`process`, `time`) VALUES (\n"
                + "(SELECT COALESCE(MAX(id),\n"
                + "  0 ) as maxID \n"
                + "    FROM DIM_PROCESS),\n"
                + "(SELECT COALESCE(MAX(id),\n"
                + "  0 ) as maxID \n"
                + "    FROM DIM_DATETIME));\n\n");

            foreach (Case caseEV in eventLog.Cases)
            {
                sql.Append("\n\n");
                sql.Append("-- Events for Case:\n");

                //sql += "Case: " + caseEV.Name + " \n";
                sql.Append("INSERT INTO `CASE` (`fact_id`) VALUES ((SELECT COALESCE(MAX(`fact_id`),0) as maxID FROM `FACT`)); \n\n");
                sql.Append("\n");

                int i = 0;
                foreach (Event eventCA in caseEV.EventList)
                {
                    String timestamp = "";
                    //Parse the dictionary with additional informations:
                    foreach (KeyValuePair<string, string> info in eventCA.Information)
                    {
                        switch (info.Key.ToLower())
                        {
                            case "timestamp":
                                //Console.WriteLine("timestamp: " + info.Value);
                                String dateString = info.Value;
                                DateTime dateValue = new DateTime();
                                if (DateTime.TryParse(dateString, out dateValue))
                                {
                                    timestamp = dateValue.ToString("yyyy-MM-dd HH:mm:ss");
                                    // "1976-04-12T22:10:00"
                                    //mysqlDateTime = dateValue.ToString(isoDateTimeFormat.SortableDateTimePattern);
                                    //Console.WriteLine(" timestamp:" + timestamp);
                                }
                                else
                                {
                                    throw new Exception("Can't convert timestamp");
                                }
                                break;
                        }
                    }

                    //sql += "Event: " + eventCA.Name + "\n";
                    sql.Append("INSERT INTO `EVENT` (`case_id`, `event`, `activity`, `sequence`, `timestamp`) VALUES "
                        + "((SELECT COALESCE(MAX(`case_id`),0) as maxID FROM `CASE`), 'PROCEDURE', '" + eventCA.Name + "', " + i + ", '" + timestamp + "');\n");
                    i++;
                }

            }

            //sql += "ROLLBACK;\n";

            sql.Append("COMMIT;\n");

            return sql.ToString();
        }
        public void EventLogAddAndGetCaseTest3()
        {
            EventLog el = new EventLog(name: "EventLogName");

            //create Case1
            Case ca = new Case("Case1");
            ca.CreateEvent("A");
            ca.CreateEvent("B");
            ca.CreateEvent("C");
            ca.CreateEvent("D");

            //create Case2
            Case ca2 = new Case("Case2");
            ca2.CreateEvent("AA");
            ca2.CreateEvent("CC");
            ca2.CreateEvent("BB");
            ca2.CreateEvent("DD");

            Case ca3 = new Case("Case3");
            ca3.CreateEvent("AAA");
            ca3.CreateEvent("CCC");
            ca3.CreateEvent("BBB");
            ca3.CreateEvent("DDD");

            el.Cases.Add(ca);
            el.Cases.Add(ca2);
            el.Cases.Add(ca3);

            Case caseGet2 = el.GetCaseByName("Case2");
            int countEvents = 0;
            foreach (Event e in caseGet2.EventList)
            {
                if (e.Name.Equals("AA")
                    || e.Name.Equals("BB")
                    || e.Name.Equals("CC")
                    || e.Name.Equals("DD"))
                {
                    countEvents++;
                }
                else
                {
                    Assert.Fail("Event not in cases and not in eventlog");
                }
            }

            if (countEvents != 4) Assert.Fail("not the right number of cases in the event log countEvents:" + countEvents);

            //
            // Overwrite test:
            //
            Case caNew3 = new Case("Case3");
            caNew3.CreateEvent("NewAAA");
            caNew3.CreateEvent("NewCCC");
            caNew3.CreateEvent("NewBBB");
            caNew3.CreateEvent("NewDDD");

            el.Cases.Add(caNew3);

            Case caseGet3 = el.GetCaseByName("Case3");

            countEvents = 0;
            foreach (Event e in caseGet3.EventList)
            {
                Debug.WriteLine("e.Name:" + e.Name);

                if (e.Name.Equals("AAA")
                    || e.Name.Equals("CCC")
                    || e.Name.Equals("BBB")
                    || e.Name.Equals("DDD"))
                {
                    countEvents++;
                }
                else if (e.Name.Equals("NewAAA")
                    || e.Name.Equals("NewCCC")
                    || e.Name.Equals("NewBBB")
                    || e.Name.Equals("NewDDD"))
                {
                    Assert.Fail("Overwrite test failed");
                }
            }

            if (countEvents != 4) Assert.Fail("not the right number of cases in the event log (countEvents:" + countEvents + ")");
        }
        /// <summary>
        /// This method creates an event log with three cases.
        /// </summary>
        /// <autor>Markus Holznagel</autor>
        public static EventLog ThreeCaseEventLog()
        {
            // Create Case 1
            Case ca1 = new Case();
            ca1.CreateEvent("A");
            ca1.CreateEvent("B");
            ca1.CreateEvent("D");
            ca1.CreateEvent("E");

            // Create Case 2
            Case ca2 = new Case();
            ca2.CreateEvent("A");
            ca2.CreateEvent("D");
            ca2.CreateEvent("B");
            ca2.CreateEvent("E");

            // Create Case 3
            Case ca3 = new Case();
            ca3.CreateEvent("A");
            ca3.CreateEvent("C");
            ca3.CreateEvent("E");

            //Create Event Log
            EventLog eventLog = new EventLog();
            eventLog.Cases.Add(ca1);
            eventLog.Cases.Add(ca2);
            eventLog.Cases.Add(ca3);

            return eventLog;
        }
        /// <summary>
        /// This method creates an complex event log from the Process Mining book 
        /// of van der Aalst site 195 Table 7.1.
        /// </summary>
        /// <autor>Markus Holznagel</autor>
        public static EventLog ComplexEventLogVanDerAalst()
        {
            //create Case1
            Case ca1 = new Case();
            ca1.CreateEvent("A");
            ca1.CreateEvent("C");
            ca1.CreateEvent("D");
            ca1.CreateEvent("E");
            ca1.CreateEvent("H");

            //create Case2
            Case ca2 = new Case();
            ca2.CreateEvent("A");
            ca2.CreateEvent("B");
            ca2.CreateEvent("D");
            ca2.CreateEvent("E");
            ca2.CreateEvent("G");

            //create Case3
            Case ca3 = new Case();
            ca3.CreateEvent("A");
            ca3.CreateEvent("D");
            ca3.CreateEvent("C");
            ca3.CreateEvent("E");
            ca3.CreateEvent("H");

            //create Case4
            Case ca4 = new Case();
            ca4.CreateEvent("A");
            ca4.CreateEvent("B");
            ca4.CreateEvent("D");
            ca4.CreateEvent("E");
            ca4.CreateEvent("H");

            //create Case5
            Case ca5 = new Case();
            ca5.CreateEvent("A");
            ca5.CreateEvent("C");
            ca5.CreateEvent("D");
            ca5.CreateEvent("E");
            ca5.CreateEvent("G");

            //create Case6
            Case ca6 = new Case();
            ca6.CreateEvent("A");
            ca6.CreateEvent("D");
            ca6.CreateEvent("C");
            ca6.CreateEvent("E");
            ca6.CreateEvent("G");

            //create Case7
            Case ca7 = new Case();
            ca7.CreateEvent("A");
            ca7.CreateEvent("D");
            ca7.CreateEvent("B");
            ca7.CreateEvent("E");
            ca7.CreateEvent("H");

            //create Case8
            Case ca8 = new Case();
            ca8.CreateEvent("A");
            ca8.CreateEvent("C");
            ca8.CreateEvent("D");
            ca8.CreateEvent("E");
            ca8.CreateEvent("F");
            ca8.CreateEvent("D");
            ca8.CreateEvent("B");
            ca8.CreateEvent("E");
            ca8.CreateEvent("H");

            //create Case9
            Case ca9 = new Case();
            ca9.CreateEvent("A");
            ca9.CreateEvent("D");
            ca9.CreateEvent("B");
            ca9.CreateEvent("E");
            ca9.CreateEvent("G");

            //create Case10
            Case ca10 = new Case();
            ca10.CreateEvent("A");
            ca10.CreateEvent("C");
            ca10.CreateEvent("D");
            ca10.CreateEvent("E");
            ca10.CreateEvent("F");
            ca10.CreateEvent("B");
            ca10.CreateEvent("D");
            ca10.CreateEvent("E");
            ca10.CreateEvent("H");

            //create Case11
            Case ca11 = new Case();
            ca11.CreateEvent("A");
            ca11.CreateEvent("C");
            ca11.CreateEvent("D");
            ca11.CreateEvent("E");
            ca11.CreateEvent("F");
            ca11.CreateEvent("B");
            ca11.CreateEvent("D");
            ca11.CreateEvent("E");
            ca11.CreateEvent("G");

            //create Case12
            Case ca12 = new Case();
            ca12.CreateEvent("A");
            ca12.CreateEvent("C");
            ca12.CreateEvent("D");
            ca12.CreateEvent("E");
            ca12.CreateEvent("F");
            ca12.CreateEvent("D");
            ca12.CreateEvent("B");
            ca12.CreateEvent("E");
            ca12.CreateEvent("G");

            //create Case13
            Case ca13 = new Case();
            ca13.CreateEvent("A");
            ca13.CreateEvent("D");
            ca13.CreateEvent("C");
            ca13.CreateEvent("E");
            ca13.CreateEvent("F");
            ca13.CreateEvent("C");
            ca13.CreateEvent("D");
            ca13.CreateEvent("E");
            ca13.CreateEvent("H");

            //create Case14
            Case ca14 = new Case();
            ca14.CreateEvent("A");
            ca14.CreateEvent("D");
            ca14.CreateEvent("C");
            ca14.CreateEvent("E");
            ca14.CreateEvent("F");
            ca14.CreateEvent("D");
            ca14.CreateEvent("B");
            ca14.CreateEvent("E");
            ca14.CreateEvent("H");

            //create Case15
            Case ca15 = new Case();
            ca15.CreateEvent("A");
            ca15.CreateEvent("D");
            ca15.CreateEvent("C");
            ca15.CreateEvent("E");
            ca15.CreateEvent("F");
            ca15.CreateEvent("B");
            ca15.CreateEvent("D");
            ca15.CreateEvent("E");
            ca15.CreateEvent("G");

            //create Case16
            Case ca16 = new Case();
            ca16.CreateEvent("A");
            ca16.CreateEvent("C");
            ca16.CreateEvent("D");
            ca16.CreateEvent("E");
            ca16.CreateEvent("F");
            ca16.CreateEvent("B");
            ca16.CreateEvent("D");
            ca16.CreateEvent("E");
            ca16.CreateEvent("F");
            ca16.CreateEvent("D");
            ca16.CreateEvent("B");
            ca16.CreateEvent("E");
            ca16.CreateEvent("G");

            //create Case17
            Case ca17 = new Case();
            ca17.CreateEvent("A");
            ca17.CreateEvent("D");
            ca17.CreateEvent("C");
            ca17.CreateEvent("E");
            ca17.CreateEvent("F");
            ca17.CreateEvent("D");
            ca17.CreateEvent("B");
            ca17.CreateEvent("E");
            ca17.CreateEvent("G");

            //create Case18
            Case ca18 = new Case();
            ca18.CreateEvent("A");
            ca18.CreateEvent("D");
            ca18.CreateEvent("C");
            ca18.CreateEvent("E");
            ca18.CreateEvent("F");
            ca18.CreateEvent("B");
            ca18.CreateEvent("D");
            ca18.CreateEvent("E");
            ca18.CreateEvent("F");
            ca18.CreateEvent("B");
            ca18.CreateEvent("D");
            ca18.CreateEvent("E");
            ca18.CreateEvent("G");

            //create Case19
            Case ca19 = new Case();
            ca19.CreateEvent("A");
            ca19.CreateEvent("D");
            ca19.CreateEvent("C");
            ca19.CreateEvent("E");
            ca19.CreateEvent("F");
            ca19.CreateEvent("D");
            ca19.CreateEvent("B");
            ca19.CreateEvent("E");
            ca19.CreateEvent("F");
            ca19.CreateEvent("B");
            ca19.CreateEvent("D");
            ca19.CreateEvent("E");
            ca19.CreateEvent("H");

            //create Case20
            Case ca20 = new Case();
            ca20.CreateEvent("A");
            ca20.CreateEvent("D");
            ca20.CreateEvent("B");
            ca20.CreateEvent("E");
            ca20.CreateEvent("F");
            ca20.CreateEvent("B");
            ca20.CreateEvent("D");
            ca20.CreateEvent("E");
            ca20.CreateEvent("F");
            ca20.CreateEvent("D");
            ca20.CreateEvent("B");
            ca20.CreateEvent("E");
            ca20.CreateEvent("G");

            //create Case21
            Case ca21 = new Case();
            ca21.CreateEvent("A");
            ca21.CreateEvent("D");
            ca21.CreateEvent("C");
            ca21.CreateEvent("E");
            ca21.CreateEvent("F");
            ca21.CreateEvent("D");
            ca21.CreateEvent("B");
            ca21.CreateEvent("E");
            ca21.CreateEvent("F");
            ca21.CreateEvent("C");
            ca21.CreateEvent("D");
            ca21.CreateEvent("E");
            ca21.CreateEvent("F");
            ca21.CreateEvent("D");
            ca21.CreateEvent("B");
            ca21.CreateEvent("E");
            ca21.CreateEvent("G");

            //create Event Log
            EventLog eventLog = new EventLog();
            eventLog.Cases.Add(ca1);
            eventLog.Cases.Add(ca2);
            eventLog.Cases.Add(ca3);
            eventLog.Cases.Add(ca4);
            eventLog.Cases.Add(ca5);
            eventLog.Cases.Add(ca6);
            eventLog.Cases.Add(ca7);
            eventLog.Cases.Add(ca8);
            eventLog.Cases.Add(ca9);
            eventLog.Cases.Add(ca10);
            eventLog.Cases.Add(ca11);
            eventLog.Cases.Add(ca12);
            eventLog.Cases.Add(ca13);
            eventLog.Cases.Add(ca14);
            eventLog.Cases.Add(ca15);
            eventLog.Cases.Add(ca16);
            eventLog.Cases.Add(ca17);
            eventLog.Cases.Add(ca18);
            eventLog.Cases.Add(ca19);
            eventLog.Cases.Add(ca20);
            eventLog.Cases.Add(ca21);

            return eventLog;
        }
        /// <summary>
        /// This method generates a simple test event log.
        /// </summary>
        /// <returns>EventLog</returns>
        /// <author>Naby Sow, Krystian Zielonka</author>
        public EventLog GenerateTestLog()
        {
            List<Case> listOfCases = new List<Case> {
                new Case("case1", new List<Event> {
                    new Event("A"),
                    new Event("B"),
                    new Event("C"),
                    new Event("D")
                }),
                new Case("case2", new List<Event> {
                    new Event("A"),
                    new Event("C"),
                    new Event("B"),
                    new Event("D")
                }),
                new Case("case3", new List<Event> {
                    new Event("A"),
                    new Event("E"),
                    new Event("D")
                }),
            };

            EventLog log = new EventLog(name: "Test") { Cases = listOfCases };

            return log;
        }
        /// <summary>
        /// This method creates an event log with one case.
        /// </summary>
        /// <autor>Thomas Meents</autor>
        public static EventLog OneCaseEventLog()
        {
            Event firstEvent = new Event("first");
            Event secondEvent = new Event("second");
            List<Event> listOfEvents = new List<Event> { firstEvent, secondEvent };
            Case ca = new Case("ExampleCase", listOfEvents);
            EventLog eventLog = new EventLog();
            eventLog.Cases.Add(ca);

            return eventLog;
        }
 /// <summary>
 /// Counts the amount of following AND-relations to a given node
 /// </summary>
 /// <param name="node">Current event node</param>
 /// <param name="log">Current event log</param>
 /// <returns>Returns the counted number of and-relations</returns>
 /// <author>Jannik Arndt</author>
 public int CountANDRelations(EventNode node, EventLog log)
 {
     var result = 0;
     for (var index = 0; index < node.ListOfFollowers.Count; index++)
         for (var index2 = index + 1; index2 < node.ListOfFollowers.Count; index2++)
         {
             try
             {
                 if (node.ListOfFollowers[index] != null && node.ListOfFollowers[index2] != null)
                     if (IsAndRelation(node.InnerEvent, node.ListOfFollowers[index].InnerEvent, node.ListOfFollowers[index2].InnerEvent, log))
                         result++;
             }
             catch (NullReferenceException)
             {
                 throw new NullReferenceException("Cannot count AND-relations");
             }
         }
     return result;
 }
        /// <summary>
        /// This method creates an event log with one case.
        /// </summary>
        /// <autor>Andrej Albrecht, Markus Holznagel</autor>
        public static EventLog OneCaseEventLogWithFourOrderedEvents()
        {
            //Create case
            Case ca = new Case();
            ca.CreateEvent("A");
            ca.CreateEvent("B");
            ca.CreateEvent("C");
            ca.CreateEvent("D");

            //Create event log
            EventLog eventLog = new EventLog();

            return eventLog;
        }
        /// <summary>
        /// Goes through the dependency-graph and creates a petrinet.
        /// </summary>
        /// <param name="dependencyGraph">An EventNode from CreateDependencyGraph()</param>
        /// <param name="eventLog">The EventLog to calculate AND and XOR-relations</param>
        /// <param name="name">The name of the new PetriNet</param>
        /// <returns>A complete petrinet</returns>
        /// <author>Jannik Arndt, Bernhard Bruns</author>
        public PetriNet CreatePetriNetFromDependencyGraph(EventNode dependencyGraph, EventLog eventLog, string name)
        {
            var petriNet = new PetriNet(name);

            // 1. first event
            var startingPlace = petriNet.AddPlace("", 1);
            var firstEvent = petriNet.AddTransition(dependencyGraph.InnerEvent.Name, incomingPlace: startingPlace);

            // 2. Go through the net and turn Nodes into Places and Transitions, with parallel structures
            HandleNodesAndCloseParallelisms(firstEvent, dependencyGraph, eventLog, petriNet);

            // 3. handle loops
            petriNet = HandleLoops(eventLog, petriNet);

            return petriNet;
        }
        /// <summary>
        /// Has a corresponding PetriNetExample: (1) -> [One] -> (2) -> [Two] -> (3)-> [Three] -> (4)-> [Four] -> (5)-> [Five] -> (6)
        /// </summary>
        /// <author>Jannik Arndt</author>
        public static EventLog OneTwoThreeFourFiveWithErrors()
        {
            var eventList1 = new List<Event>
            {
                new Event("One"),
                new Event("Two"),
                new Event("Three"),
                new Event("Four"),
                new Event("Five")
            };

            var eventList2 = new List<Event>
            {
                new Event("One"),
                new Event("Two"),
                new Event("Forty-Two"),
                new Event("Four"),
                new Event("Five")
            };

            var eventList3 = new List<Event>
            {
                new Event("One"),
                new Event("Five"),
                new Event("Three"),
                new Event("Four"),
                new Event("Two")
            };

            var caseList = new List<Case>
            {
                new Case("Case1", eventList1),
                new Case("Case2", eventList2),
                new Case("Case3", eventList3)
            };

            var eventLog = new EventLog { Cases = caseList };

            return eventLog;
        }
示例#41
0
        /// <summary>
        /// Depending on the count of followers this adds one (or more) places and their following transitions.
        /// </summary>
        /// <param name="event1"></param>
        /// <param name="node">An event node</param>
        /// <param name="log">The current event log</param>
        /// <param name="petriNet"></param>
        /// <returns>The newly added transitions. This is where you need to continue working.</returns>
        /// <exception cref="NotImplementedException">If there are more than 3 followers in a non-trivial relation.</exception>
        /// <author>Jannik Arndt</author>
        public List <Transition> HandleNode(Transition event1, EventNode node, EventLog log, PetriNet petriNet)
        {
            // Case: No followers
            if (node.ListOfFollowers.Count == 0)
            {
                return(new List <Transition>());
            }

            // one or more more followers => count the AND-relations
            var andRelations = CountANDRelations(node, log);

            // Case: All nodes are AND-related
            if (andRelations == node.ListOfFollowers.Count)
            {
                return(StartAND(event1, node.ListOfFollowers, petriNet));
            }

            // Case: All nodes are XOR-related
            if (andRelations == 0)
            {
                return(StartXOR(event1, node.ListOfFollowers, petriNet));
            }

            // Case: 3 Followers
            if (node.ListOfFollowers.Count == 3)
            {
                var x = node;
                var a = node.ListOfFollowers[0];
                var b = node.ListOfFollowers[1];
                var c = node.ListOfFollowers[2];

                if (andRelations == 2) // XOR-Relations == 1
                {
                    // There are two and-relations and one xor-relation. Find the xor and order the parameters accordingly
                    if (IsXorRelation(x.InnerEvent, b.InnerEvent, c.InnerEvent, log))
                    {
                        return(StartAand_BxorC(event1, a, b, c, petriNet));
                    }
                    if (IsXorRelation(x.InnerEvent, a.InnerEvent, c.InnerEvent, log))
                    {
                        return(StartAand_BxorC(event1, b, a, c, petriNet));
                    }
                    if (IsXorRelation(x.InnerEvent, a.InnerEvent, b.InnerEvent, log))
                    {
                        return(StartAand_BxorC(event1, c, a, b, petriNet));
                    }
                }
                else // XOR-Relations == 2 && AND-Relations == 1
                {
                    // There are two xor-relations and one and-relation. Find the and and order the parameters accordingly
                    if (IsAndRelation(x.InnerEvent, b.InnerEvent, c.InnerEvent, log))
                    {
                        return(StartAxor_BandC(event1, a, b, c, petriNet));
                    }
                    if (IsAndRelation(x.InnerEvent, a.InnerEvent, c.InnerEvent, log))
                    {
                        return(StartAxor_BandC(event1, b, a, c, petriNet));
                    }
                    if (IsAndRelation(x.InnerEvent, a.InnerEvent, b.InnerEvent, log))
                    {
                        return(StartAxor_BandC(event1, c, a, b, petriNet));
                    }
                }
            }
            if (node.ListOfFollowers.Count > 3)
            {
                return(StartXOR(event1, node.ListOfFollowers, petriNet));
            }

            // optional transition
            if (node.ListOfFollowers.Count == 2)
            {
                if (log.EventFollowsEvent(node.ListOfFollowers[0].InnerEvent, node.ListOfFollowers[1].InnerEvent) > 0)
                {
                    return(StartOptionalTransition(event1, node.ListOfFollowers[0].InnerEvent.Name, node.ListOfFollowers[1].InnerEvent.Name, petriNet));
                }
                else if (log.EventFollowsEvent(node.ListOfFollowers[1].InnerEvent, node.ListOfFollowers[0].InnerEvent) > 0)
                {
                    return(StartOptionalTransition(event1, node.ListOfFollowers[1].InnerEvent.Name, node.ListOfFollowers[0].InnerEvent.Name, petriNet));
                }
            }

            return(null);
        }
        /// <summary>
        /// This method creates an event log with two cases.
        /// </summary>
        /// <autor>Markus Holznagel</autor>
        public static EventLog TwoCaseEventLog()
        {
            //Create case1
            Case ca = new Case();
            ca.CreateEvent("A");
            ca.CreateEvent("B");
            ca.CreateEvent("C");
            ca.CreateEvent("D");

            //Create case2
            Case ca2 = new Case();
            ca2.CreateEvent("A");
            ca2.CreateEvent("C");
            ca2.CreateEvent("B");
            ca2.CreateEvent("D");

            //Create event log
            EventLog eventLog = new EventLog();
            eventLog.Cases.Add(ca);
            eventLog.Cases.Add(ca2);

            return eventLog;
        }
示例#43
0
        public void CompareEventLogAndPetriNetTest1()
        {
            //
            //EventLog
            //
            //create Case1
            Case ca1 = new Case();

            ca1.CreateEvent("A");
            ca1.CreateEvent("C");
            ca1.CreateEvent("D");
            ca1.CreateEvent("E");
            ca1.CreateEvent("H");

            //create Case2
            Case ca2 = new Case();

            ca2.CreateEvent("A");
            ca2.CreateEvent("B");
            ca2.CreateEvent("D");
            ca2.CreateEvent("E");
            ca2.CreateEvent("G");

            //create Case3
            Case ca3 = new Case();

            ca3.CreateEvent("A");
            ca3.CreateEvent("D");
            ca3.CreateEvent("C");
            ca3.CreateEvent("E");
            ca3.CreateEvent("H");

            //create Case4
            Case ca4 = new Case();

            ca4.CreateEvent("A");
            ca4.CreateEvent("B");
            ca4.CreateEvent("D");
            ca4.CreateEvent("E");
            ca4.CreateEvent("H");

            //create Case5
            Case ca5 = new Case();

            ca5.CreateEvent("A");
            ca5.CreateEvent("C");
            ca5.CreateEvent("D");
            ca5.CreateEvent("E");
            ca5.CreateEvent("G");

            //create Case6
            Case ca6 = new Case();

            ca6.CreateEvent("A");
            ca6.CreateEvent("D");
            ca6.CreateEvent("C");
            ca6.CreateEvent("E");
            ca6.CreateEvent("G");

            //create Case7
            Case ca7 = new Case();

            ca7.CreateEvent("A");
            ca7.CreateEvent("D");
            ca7.CreateEvent("B");
            ca7.CreateEvent("E");
            ca7.CreateEvent("H");

            //create Case8
            Case ca8 = new Case();

            ca8.CreateEvent("A");
            ca8.CreateEvent("C");
            ca8.CreateEvent("D");
            ca8.CreateEvent("E");
            ca8.CreateEvent("F");
            ca8.CreateEvent("D");
            ca8.CreateEvent("B");
            ca8.CreateEvent("E");
            ca8.CreateEvent("H");

            //create Case9
            Case ca9 = new Case();

            ca9.CreateEvent("A");
            ca9.CreateEvent("D");
            ca9.CreateEvent("B");
            ca9.CreateEvent("E");
            ca9.CreateEvent("G");

            //create Case10
            Case ca10 = new Case();

            ca10.CreateEvent("A");
            ca10.CreateEvent("C");
            ca10.CreateEvent("D");
            ca10.CreateEvent("E");
            ca10.CreateEvent("F");
            ca10.CreateEvent("B");
            ca10.CreateEvent("D");
            ca10.CreateEvent("E");
            ca10.CreateEvent("H");

            //create Case11
            Case ca11 = new Case();

            ca11.CreateEvent("A");
            ca11.CreateEvent("C");
            ca11.CreateEvent("D");
            ca11.CreateEvent("E");
            ca11.CreateEvent("F");
            ca11.CreateEvent("B");
            ca11.CreateEvent("D");
            ca11.CreateEvent("E");
            ca11.CreateEvent("G");

            //create Case12
            Case ca12 = new Case();

            ca12.CreateEvent("A");
            ca12.CreateEvent("C");
            ca12.CreateEvent("D");
            ca12.CreateEvent("E");
            ca12.CreateEvent("F");
            ca12.CreateEvent("D");
            ca12.CreateEvent("B");
            ca12.CreateEvent("E");
            ca12.CreateEvent("G");

            //create Case13
            Case ca13 = new Case();

            ca13.CreateEvent("A");
            ca13.CreateEvent("D");
            ca13.CreateEvent("C");
            ca13.CreateEvent("E");
            ca13.CreateEvent("F");
            ca13.CreateEvent("C");
            ca13.CreateEvent("D");
            ca13.CreateEvent("E");
            ca13.CreateEvent("H");

            //create Case14
            Case ca14 = new Case();

            ca14.CreateEvent("A");
            ca14.CreateEvent("D");
            ca14.CreateEvent("C");
            ca14.CreateEvent("E");
            ca14.CreateEvent("F");
            ca14.CreateEvent("D");
            ca14.CreateEvent("B");
            ca14.CreateEvent("E");
            ca14.CreateEvent("H");

            //create Case15
            Case ca15 = new Case();

            ca15.CreateEvent("A");
            ca15.CreateEvent("D");
            ca15.CreateEvent("C");
            ca15.CreateEvent("E");
            ca15.CreateEvent("F");
            ca15.CreateEvent("B");
            ca15.CreateEvent("D");
            ca15.CreateEvent("E");
            ca15.CreateEvent("G");

            //create Case16
            Case ca16 = new Case();

            ca16.CreateEvent("A");
            ca16.CreateEvent("C");
            ca16.CreateEvent("D");
            ca16.CreateEvent("E");
            ca16.CreateEvent("F");
            ca16.CreateEvent("B");
            ca16.CreateEvent("D");
            ca16.CreateEvent("E");
            ca16.CreateEvent("F");
            ca16.CreateEvent("D");
            ca16.CreateEvent("B");
            ca16.CreateEvent("E");
            ca16.CreateEvent("G");

            //create Case17
            Case ca17 = new Case();

            ca17.CreateEvent("A");
            ca17.CreateEvent("D");
            ca17.CreateEvent("C");
            ca17.CreateEvent("E");
            ca17.CreateEvent("F");
            ca17.CreateEvent("D");
            ca17.CreateEvent("B");
            ca17.CreateEvent("E");
            ca17.CreateEvent("G");

            //create Case18
            Case ca18 = new Case();

            ca18.CreateEvent("A");
            ca18.CreateEvent("D");
            ca18.CreateEvent("C");
            ca18.CreateEvent("E");
            ca18.CreateEvent("F");
            ca18.CreateEvent("B");
            ca18.CreateEvent("D");
            ca18.CreateEvent("E");
            ca18.CreateEvent("F");
            ca18.CreateEvent("B");
            ca18.CreateEvent("D");
            ca18.CreateEvent("E");
            ca18.CreateEvent("G");

            //create Case19
            Case ca19 = new Case();

            ca19.CreateEvent("A");
            ca19.CreateEvent("D");
            ca19.CreateEvent("C");
            ca19.CreateEvent("E");
            ca19.CreateEvent("F");
            ca19.CreateEvent("D");
            ca19.CreateEvent("B");
            ca19.CreateEvent("E");
            ca19.CreateEvent("F");
            ca19.CreateEvent("B");
            ca19.CreateEvent("D");
            ca19.CreateEvent("E");
            ca19.CreateEvent("H");

            //create Case20
            Case ca20 = new Case();

            ca20.CreateEvent("A");
            ca20.CreateEvent("D");
            ca20.CreateEvent("B");
            ca20.CreateEvent("E");
            ca20.CreateEvent("F");
            ca20.CreateEvent("B");
            ca20.CreateEvent("D");
            ca20.CreateEvent("E");
            ca20.CreateEvent("F");
            ca20.CreateEvent("D");
            ca20.CreateEvent("B");
            ca20.CreateEvent("E");
            ca20.CreateEvent("G");

            //create Case21
            Case ca21 = new Case();

            ca21.CreateEvent("A");
            ca21.CreateEvent("D");
            ca21.CreateEvent("C");
            ca21.CreateEvent("E");
            ca21.CreateEvent("F");
            ca21.CreateEvent("D");
            ca21.CreateEvent("B");
            ca21.CreateEvent("E");
            ca21.CreateEvent("F");
            ca21.CreateEvent("C");
            ca21.CreateEvent("D");
            ca21.CreateEvent("E");
            ca21.CreateEvent("F");
            ca21.CreateEvent("D");
            ca21.CreateEvent("B");
            ca21.CreateEvent("E");
            ca21.CreateEvent("G");

            //create Event Log
            EventLog eventLog = new EventLog();

            eventLog.Cases.Add(ca1);
            eventLog.Cases.Add(ca2);
            eventLog.Cases.Add(ca3);
            eventLog.Cases.Add(ca4);
            eventLog.Cases.Add(ca5);
            eventLog.Cases.Add(ca6);
            eventLog.Cases.Add(ca7);
            eventLog.Cases.Add(ca8);
            eventLog.Cases.Add(ca9);
            eventLog.Cases.Add(ca10);
            eventLog.Cases.Add(ca11);
            eventLog.Cases.Add(ca12);
            eventLog.Cases.Add(ca13);
            eventLog.Cases.Add(ca14);
            eventLog.Cases.Add(ca15);
            eventLog.Cases.Add(ca16);
            eventLog.Cases.Add(ca17);
            eventLog.Cases.Add(ca18);
            eventLog.Cases.Add(ca19);
            eventLog.Cases.Add(ca20);
            eventLog.Cases.Add(ca21);


            //
            //PetriNet
            //
            PetriNet petriNet = new PetriNet("Petri-Net Name");

            Place pStart = new Place("Place Start", 0);
            Place pC1    = new Place("c1", 0);
            Place pC2    = new Place("c2", 0);
            Place pC3    = new Place("c3", 0);
            Place pC4    = new Place("c4", 0);
            Place pC5    = new Place("c5", 0);
            Place pEnd   = new Place("Place End", 0);

            Transition tA = new Transition("A");
            Transition tB = new Transition("B");
            Transition tC = new Transition("C");
            Transition tD = new Transition("D");
            Transition tE = new Transition("E");
            Transition tF = new Transition("F");
            Transition tG = new Transition("G");
            Transition tH = new Transition("H");

            tG.AddOutgoingPlace(pEnd);
            tG.AddIncomingPlace(pC5);

            tH.AddOutgoingPlace(pEnd);
            tH.AddIncomingPlace(pC5);

            tE.AddIncomingPlace(pC3);
            tE.AddIncomingPlace(pC4);
            tE.AddOutgoingPlace(pC5);

            pC3.AppendIncomingTransition(tB);
            pC3.AppendIncomingTransition(tC);
            pC3.AppendOutgoingTransition(tE);

            pC4.AppendIncomingTransition(tD);
            pC4.AppendOutgoingTransition(tE);

            tB.AddIncomingPlace(pC1);
            tB.AddOutgoingPlace(pC3);

            tC.AddIncomingPlace(pC1);
            tC.AddOutgoingPlace(pC3);

            tD.AddIncomingPlace(pC2);
            tD.AddOutgoingPlace(pC4);

            pC1.AppendIncomingTransition(tA);
            pC1.AppendOutgoingTransition(tB);
            pC1.AppendOutgoingTransition(tC);

            pC2.AppendIncomingTransition(tA);
            pC2.AppendOutgoingTransition(tD);

            tF.AddIncomingPlace(pC5);
            tF.AddOutgoingPlace(pC1);
            tF.AddOutgoingPlace(pC2);

            //
            tA.AddIncomingPlace(pStart);
            tA.AddOutgoingPlace(pC1);
            tA.AddOutgoingPlace(pC2);

            pStart.AppendOutgoingTransition(tA);

            pEnd.AppendIncomingTransition(tG);
            pEnd.AppendIncomingTransition(tH);

            ////
            petriNet.Transitions.Add(tA);
            petriNet.Transitions.Add(tB);
            petriNet.Transitions.Add(tC);
            petriNet.Transitions.Add(tD);
            petriNet.Transitions.Add(tE);
            petriNet.Transitions.Add(tF);
            petriNet.Transitions.Add(tG);
            petriNet.Transitions.Add(tH);

            ////
            petriNet.Places.Add(pStart);
            petriNet.Places.Add(pC1);
            petriNet.Places.Add(pC2);
            petriNet.Places.Add(pC3);
            petriNet.Places.Add(pC4);
            petriNet.Places.Add(pC5);
            petriNet.Places.Add(pEnd);

            ComparingFootprint footprintEventLog = ComparingFootprintAlgorithm.CreateFootprint(eventLog);
            ComparingFootprint footprintPetriNet = ComparingFootprintAlgorithm.CreateFootprint(petriNet);

            ComparingFootprintResultMatrix footprintResultMatrix = new ComparingFootprintResultMatrix(footprintEventLog, footprintPetriNet);

            if (footprintResultMatrix.HeaderWithEventNames.Count != 8)
            {
                Assert.Fail("");
            }

            int y = 0;

            foreach (String headerNameY in footprintResultMatrix.HeaderWithEventNames)
            {
                int x = 0;
                foreach (String headerNameX in footprintResultMatrix.HeaderWithEventNames)
                {
                    ResultCellType resultCellType = footprintResultMatrix.ResultMatrix[y, x];
                    Console.WriteLine("Test headerNameY: " + headerNameY + ", headerNameX: " + headerNameX + " [" + y + "," + x + "].CellType:" + resultCellType);


                    if (!resultCellType.Equals(ResultCellType.NoDifferences))
                    {
                        Assert.Fail("Test headerNameY: " + headerNameY + ", headerNameX: " + headerNameX + " [" + y + "," + x + "].CellType:" + resultCellType);
                    }



                    x++;
                }
                y++;
            }

            //Arrange (Create Footprints)
            ComparingFootprint             footPrintEventlog = ComparingFootprintAlgorithm.CreateFootprint(eventLog);
            ComparingFootprint             footPrintPetrinet = ComparingFootprintAlgorithm.CreateFootprint(petriNet);
            ComparingFootprintResultMatrix resultFootprint   = new ComparingFootprintResultMatrix(footPrintEventlog, footPrintPetrinet);

            // Act (Calculate Fitness)
            double fitnessComparingFootprint = ComparingFootprintAlgorithm.CalculateFitness(resultFootprint.GetNumberOfDifferences(), resultFootprint.GetNumberOfOpportunities());


            if (fitnessComparingFootprint != 1.0)
            {
                // Assert
                Assert.Fail("Fitness not correct! (" + fitnessComparingFootprint + ")");
            }
        }