Example #1
0
        /// <summary>
        /// Adds an optional Transition to the net, as well as the next mandatory transition.
        /// </summary>
        /// <param name="startingTransition">The existing transition</param>
        /// <param name="optionalAction">The optional transition</param>
        /// <param name="commonAction">The mandatory transition</param>
        /// <param name="petriNet"></param>
        /// <returns></returns>
        /// <author>Jannik Arndt</author>
        public List <Transition> StartOptionalTransition(Transition startingTransition, String optionalAction, String commonAction, PetriNet petriNet)
        {
            var place1 = petriNet.AddPlace();
            var place2 = petriNet.AddPlace();

            startingTransition.AddOutgoingPlace(place1);
            petriNet.AddTransition(optionalAction, incomingPlace: place1, outgoingPlace: place2);
            var commonTransition = petriNet.AddTransition(commonAction, new List <Place> {
                place1, place2
            });

            return(new List <Transition> {
                commonTransition
            });
        }
Example #2
0
        /// <summary>
        /// (1) -> [One] -> (3)-> [Three] -> (5)-> [Five] -> (6)
        /// Has a corresponding EventLog!
        /// </summary>
        /// <author>Thomas Meents</author>
        public static PetriNet OneThreeFive()
        {
            var petriNet = new PetriNet("OneThreeFive");

            var place1 = petriNet.AddPlace("1");
            var place3 = petriNet.AddPlace("3");
            var place5 = petriNet.AddPlace("5");
            var place6 = petriNet.AddPlace("6");

            petriNet.AddTransition("One", incomingPlace: place1, outgoingPlace: place3);
            petriNet.AddTransition("Three", incomingPlace: place3, outgoingPlace: place5);
            petriNet.AddTransition("Five", incomingPlace: place5, outgoingPlace: place6);

            return(petriNet);
        }
Example #3
0
        /// <summary>
        /// Adds a place for each transition, then combines these places in the given transition.
        /// </summary>
        /// <param name="startingTransition">The starting transition</param>
        /// <param name="petriNet">The current petri net</param>
        /// <param name="endingTransition">The ending transition, if it exists already. Otherwise a new one is created></param>
        /// <returns>The transition where the places after the AND-related-events are connected.</returns>
        /// <author>Jannik Arndt</author>
        public List <Transition> EndAND(List <Transition> startingTransition, PetriNet petriNet, Transition endingTransition = null)
        {
            if (endingTransition == null)
            {
                endingTransition = petriNet.AddTransition();
            }

            if (_openParallelismCount.Count > 0)
            {
                _openParallelismCount.Pop();
            }

            var listOfClosingPlaces = new List <Place>();

            foreach (var transition in startingTransition)
            {
                var newPlace = petriNet.AddPlace();
                transition.AddOutgoingPlace(newPlace);
                listOfClosingPlaces.Add(newPlace);
            }
            endingTransition.AddIncomingPlaces(listOfClosingPlaces);
            return(new List <Transition> {
                endingTransition
            });
        }
Example #4
0
        public void MutableNetContent()
        {
            var net    = new PetriNet <int>();
            var place1 = net.AddPlace("P1");

            CollectionAssert.AreEquivalent(new[] { place1 }, net.Places);
            CollectionAssert.IsEmpty(net.Transitions);
            CollectionAssert.IsEmpty(net.Arcs);
            AssertHasVertices(net.Graph, new[] { place1 });
            AssertNoEdge(net.Graph);

            var transition1 = net.AddTransition("T1");

            CollectionAssert.AreEquivalent(new[] { place1 }, net.Places);
            CollectionAssert.AreEquivalent(new[] { transition1 }, net.Transitions);
            CollectionAssert.IsEmpty(net.Arcs);
            AssertHasVertices(net.Graph, new IPetriVertex[] { place1, transition1 });
            AssertNoEdge(net.Graph);

            var place2      = net.AddPlace("P2");
            var transition2 = net.AddTransition("T2");
            var place3      = net.AddPlace("P3");

            CollectionAssert.AreEquivalent(new[] { place1, place2, place3 }, net.Places);
            CollectionAssert.AreEquivalent(new[] { transition1, transition2 }, net.Transitions);
            CollectionAssert.IsEmpty(net.Arcs);
            AssertHasVertices(net.Graph, new IPetriVertex[] { place1, place2, place3, transition1, transition2 });
            AssertNoEdge(net.Graph);

            var arc1 = net.AddArc(place1, transition1);

            CollectionAssert.AreEquivalent(new[] { place1, place2, place3 }, net.Places);
            CollectionAssert.AreEquivalent(new[] { transition1, transition2 }, net.Transitions);
            CollectionAssert.AreEquivalent(new[] { arc1 }, net.Arcs);
            AssertHasVertices(net.Graph, new IPetriVertex[] { place1, place2, place3, transition1, transition2 });
            AssertHasEdges(net.Graph, new[] { arc1 });

            var arc2 = net.AddArc(transition2, place3);
            var arc3 = net.AddArc(place2, transition2);

            CollectionAssert.AreEquivalent(new[] { place1, place2, place3 }, net.Places);
            CollectionAssert.AreEquivalent(new[] { transition1, transition2 }, net.Transitions);
            CollectionAssert.AreEquivalent(new[] { arc1, arc2, arc3 }, net.Arcs);
            AssertHasVertices(net.Graph, new IPetriVertex[] { place1, place2, place3, transition1, transition2 });
            AssertHasEdges(net.Graph, new[] { arc1, arc2, arc3 });
        }
Example #5
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);
        }
Example #6
0
 /// <summary>
 /// Connects all open endings to one end-place. This is useful for multiple processmodels in one net or for loops at the end of the net.
 /// </summary>
 /// <param name="petriNet">A petrinet with possible open endings</param>
 /// <returns>The given PetriNet with a fixed ending</returns>
 /// <author>Jannik Arndt</author>
 public PetriNet FixEnding(PetriNet petriNet)
 {
     if (petriNet.GetTransitionsWithoutFollowersIgnoreLoops().Count > 0)
     {
         var endingPlace = petriNet.AddPlace("End");
         foreach (var transition in petriNet.GetTransitionsWithoutFollowersIgnoreLoops())
         {
             if (transition.OutgoingPlaces.Count > 0)
             {
                 var temporaryTransition = petriNet.AddTransition();
                 transition.OutgoingPlaces[0].AppendOutgoingTransition(temporaryTransition);
                 temporaryTransition.AddIncomingPlace(transition.OutgoingPlaces[0]);
                 temporaryTransition.AddOutgoingPlace(endingPlace);
             }
             else
             {
                 transition.AddOutgoingPlace(endingPlace);
             }
         }
     }
     return(petriNet);
 }
Example #7
0
        /// <summary>
        /// Adds as many places as following events that each lead to a transition.
        /// </summary>
        /// <param name="startingTransition">Contains the starting transition</param>
        /// <param name="followers">node.followers</param>
        /// <param name="petriNet">Contains the current petri net</param>
        /// <returns>The transitions that are in an AND-relation.</returns>
        /// <author>Jannik Arndt</author>
        public List <Transition> StartAND(Transition startingTransition, List <EventNode> followers, PetriNet petriNet)
        {
            for (var index = 0; index < followers.Count; index++)
            {
                _openParallelismCount.Push(Parallelism.And);
            }
            var listOfFollowingTransitions = new List <Transition>();

            if (startingTransition.Name == "")
            {
                startingTransition.Name = "AND Split";
            }
            startingTransition.IsANDSplit = true;

            foreach (var node in followers)
            {
                var newPlace = petriNet.AddPlace();

                listOfFollowingTransitions.Add(petriNet.AddTransition(node.InnerEvent.Name, incomingPlace: newPlace));
                startingTransition.AddOutgoingPlace(newPlace);
            }
            return(listOfFollowingTransitions);
        }
Example #8
0
        public void Clone()
        {
            var net = new PetriNet <int>();

            AssertEmpty(net);

            var clonedNet = net.Clone();

            Assert.IsNotNull(clonedNet);
            AssertEmpty(clonedNet);

            clonedNet = (PetriNet <int>)((ICloneable)net).Clone();
            Assert.IsNotNull(clonedNet);
            AssertEmpty(clonedNet);

            var place1      = net.AddPlace("p1");
            var place2      = net.AddPlace("p2");
            var transition1 = net.AddTransition("t1");

            AssertHasVertices(net.Graph, new IPetriVertex[] { place1, place2, transition1 });
            AssertNoEdge(net.Graph);

            clonedNet = net.Clone();
            Assert.IsNotNull(clonedNet);
            AssertAreEqual(net, clonedNet);

            clonedNet = (PetriNet <int>)((ICloneable)net).Clone();
            Assert.IsNotNull(clonedNet);
            AssertAreEqual(net, clonedNet);

            var place3      = net.AddPlace("p3");
            var transition2 = net.AddTransition("t2");
            var arc1        = net.AddArc(place1, transition1);
            var arc2        = net.AddArc(place2, transition1);
            var arc3        = net.AddArc(place3, transition2);
            var arc4        = net.AddArc(transition1, place3);
            var arc5        = net.AddArc(transition2, place1);

            AssertHasVertices(net.Graph, new IPetriVertex[] { place1, place2, place3, transition1, transition2 });
            AssertHasEdges(net.Graph, new[] { arc1, arc2, arc3, arc4, arc5 });

            clonedNet = net.Clone();
            Assert.IsNotNull(clonedNet);
            AssertAreEqual(net, clonedNet);

            clonedNet = (PetriNet <int>)((ICloneable)net).Clone();
            Assert.IsNotNull(clonedNet);
            AssertAreEqual(net, clonedNet);

            var place4      = net.AddPlace("p4");
            var transition3 = net.AddTransition("t3");

            AssertHasVertices(net.Graph, new IPetriVertex[] { place1, place2, place3, place4, transition1, transition2, transition3 });
            AssertHasEdges(net.Graph, new[] { arc1, arc2, arc3, arc4, arc5 });

            clonedNet = net.Clone();
            Assert.IsNotNull(clonedNet);
            AssertAreEqual(net, clonedNet);

            clonedNet = (PetriNet <int>)((ICloneable)net).Clone();
            Assert.IsNotNull(clonedNet);
            AssertAreEqual(net, clonedNet);

            #region Local function

            void AssertEmpty <TToken>(PetriNet <TToken> n)
            {
                CollectionAssert.IsEmpty(n.Places);
                CollectionAssert.IsEmpty(n.Transitions);
                CollectionAssert.IsEmpty(n.Arcs);
                AssertEmptyGraph(n.Graph);
            }

            void AssertAreEqual <TToken>(PetriNet <TToken> expected, PetriNet <TToken> actual)
            {
                CollectionAssert.AreEqual(expected.Places, actual.Places);
                CollectionAssert.AreEqual(expected.Transitions, actual.Transitions);
                CollectionAssert.AreEqual(expected.Arcs, actual.Arcs);
                AssertEquivalentGraphs(expected.Graph, actual.Graph);
            }

            #endregion
        }
Example #9
0
        public void ObjectToString()
        {
            var    net            = new PetriNet <int>();
            string expectedString =
                "-----------------------------------------------" + Environment.NewLine +
                "Places (0)" + Environment.NewLine +
                "Transitions (0)" + Environment.NewLine +
                "Arcs" + Environment.NewLine;

            Assert.AreEqual(expectedString, net.ToString());

            var place1 = net.AddPlace("TestPlace");

            expectedString =
                "-----------------------------------------------" + Environment.NewLine +
                "Places (1)" + Environment.NewLine +
                "\tP(TestPlace|0)" + Environment.NewLine +
                Environment.NewLine +
                "Transitions (0)" + Environment.NewLine +
                "Arcs" + Environment.NewLine;
            Assert.AreEqual(expectedString, net.ToString());

            place1.Marking.Add(1);
            place1.Marking.Add(5);
            var place2 = net.AddPlace("TestPlace2");

            expectedString =
                "-----------------------------------------------" + Environment.NewLine +
                "Places (2)" + Environment.NewLine +
                "\tP(TestPlace|2)" + Environment.NewLine +
                "\tInt32" + Environment.NewLine +
                "\tInt32" + Environment.NewLine +
                Environment.NewLine +
                "\tP(TestPlace2|0)" + Environment.NewLine +
                Environment.NewLine +
                "Transitions (0)" + Environment.NewLine +
                "Arcs" + Environment.NewLine;
            Assert.AreEqual(expectedString, net.ToString());

            var transition = net.AddTransition("Transition");

            expectedString =
                "-----------------------------------------------" + Environment.NewLine +
                "Places (2)" + Environment.NewLine +
                "\tP(TestPlace|2)" + Environment.NewLine +
                "\tInt32" + Environment.NewLine +
                "\tInt32" + Environment.NewLine +
                Environment.NewLine +
                "\tP(TestPlace2|0)" + Environment.NewLine +
                Environment.NewLine +
                "Transitions (1)" + Environment.NewLine +
                "\tT(Transition)" + Environment.NewLine +
                Environment.NewLine +
                "Arcs" + Environment.NewLine;
            Assert.AreEqual(expectedString, net.ToString());

            net.AddArc(place1, transition);
            net.AddArc(transition, place2);
            expectedString =
                "-----------------------------------------------" + Environment.NewLine +
                "Places (2)" + Environment.NewLine +
                "\tP(TestPlace|2)" + Environment.NewLine +
                "\tInt32" + Environment.NewLine +
                "\tInt32" + Environment.NewLine +
                Environment.NewLine +
                "\tP(TestPlace2|0)" + Environment.NewLine +
                Environment.NewLine +
                "Transitions (1)" + Environment.NewLine +
                "\tT(Transition)" + Environment.NewLine +
                Environment.NewLine +
                "Arcs" + Environment.NewLine +
                "\tP(TestPlace|2) -> T(Transition)" + Environment.NewLine +
                "\tT(Transition) -> P(TestPlace2|0)" + Environment.NewLine;
            Assert.AreEqual(expectedString, net.ToString());
        }
        public void Simulate()
        {
            #region Petri Net setup

            var net = new PetriNet <Person>();

            // Places
            var customerAtEntrance = net.AddPlace("Customer in front of barber");
            var customerWaiting    = net.AddPlace("Customer waiting");
            var cutting            = net.AddPlace("Cutting");
            var idle              = net.AddPlace("Idle barber");
            var customerPaying    = net.AddPlace("Customer paying");
            var customerNotPaying = net.AddPlace("Customer not paying");
            var customerOut       = net.AddPlace("Customer out");

            // Transitions
            var enter = net.AddTransition("Enter");

            var startCutting = net.AddTransition("Start cutting");
            startCutting.Condition = new CustomerWaitingAndBarberReady();

            var finishCutting = net.AddTransition("Finish cutting");
            finishCutting.Condition = new CustomerHairCutAndBarberFinished();

            var exit = net.AddTransition("Exit");
            exit.Condition = new CustomerPaid();

            // Arcs
            net.AddArc(customerAtEntrance, enter);

            net.AddArc(enter, customerWaiting);

            var goToChair = net.AddArc(customerWaiting, startCutting);
            goToChair.Annotation = new GoToChair();

            net.AddArc(startCutting, cutting);
            net.AddArc(cutting, finishCutting);

            var goToIdle = net.AddArc(finishCutting, idle);
            goToIdle.Annotation = new GoToIdle();

            net.AddArc(idle, startCutting);

            var goToPay = net.AddArc(finishCutting, customerPaying);
            goToPay.Annotation = new GoToPay();

            var notPay = net.AddArc(finishCutting, customerNotPaying);
            notPay.Annotation = new NoRobber();

            net.AddArc(customerPaying, exit);
            net.AddArc(customerNotPaying, exit);
            net.AddArc(exit, customerOut);

            var jean   = new Customer("Jean");
            var daniel = new Customer("Daniel");
            customerAtEntrance.Marking.Add(jean);
            customerAtEntrance.Marking.Add(daniel);

            var joe = new Barber("Joe");
            idle.Marking.Add(joe);

            #endregion

            // Run simulation
            var simulator = new PetriNetSimulator <Person>(net);
            simulator.Initialize();
            CollectionAssert.AreEquivalent(new[] { jean, daniel }, customerAtEntrance.Marking);
            CollectionAssert.IsEmpty(customerWaiting.Marking);
            CollectionAssert.IsEmpty(cutting.Marking);
            CollectionAssert.AreEquivalent(new[] { joe }, idle.Marking);
            CollectionAssert.IsEmpty(customerPaying.Marking);
            CollectionAssert.IsEmpty(customerNotPaying.Marking);
            CollectionAssert.IsEmpty(customerOut.Marking);

            simulator.SimulateStep();
            CollectionAssert.IsEmpty(customerAtEntrance.Marking);
            CollectionAssert.AreEquivalent(new[] { jean, daniel }, customerWaiting.Marking);
            CollectionAssert.IsEmpty(cutting.Marking);
            CollectionAssert.AreEquivalent(new[] { joe }, idle.Marking);
            CollectionAssert.IsEmpty(customerPaying.Marking);
            CollectionAssert.IsEmpty(customerNotPaying.Marking);
            CollectionAssert.IsEmpty(customerOut.Marking);

            simulator.SimulateStep();
            CollectionAssert.IsEmpty(customerAtEntrance.Marking);
            CollectionAssert.AreEquivalent(new[] { daniel }, customerWaiting.Marking);
            CollectionAssert.AreEquivalent(new Person[] { joe, jean }, cutting.Marking);
            CollectionAssert.IsEmpty(idle.Marking);
            CollectionAssert.IsEmpty(customerPaying.Marking);
            CollectionAssert.IsEmpty(customerNotPaying.Marking);
            CollectionAssert.IsEmpty(customerOut.Marking);

            simulator.SimulateStep();
            CollectionAssert.IsEmpty(customerAtEntrance.Marking);
            CollectionAssert.AreEquivalent(new[] { daniel }, customerWaiting.Marking);
            CollectionAssert.IsEmpty(cutting.Marking);
            CollectionAssert.AreEquivalent(new[] { joe }, idle.Marking);
            CollectionAssert.AreEquivalent(new[] { jean }, customerPaying.Marking);
            CollectionAssert.IsEmpty(customerNotPaying.Marking);
            CollectionAssert.IsEmpty(customerOut.Marking);

            simulator.SimulateStep();
            CollectionAssert.IsEmpty(customerAtEntrance.Marking);
            CollectionAssert.IsEmpty(customerWaiting.Marking);
            CollectionAssert.AreEquivalent(new Person[] { joe, daniel }, cutting.Marking);
            CollectionAssert.IsEmpty(idle.Marking);
            CollectionAssert.IsEmpty(customerPaying.Marking);
            CollectionAssert.IsEmpty(customerNotPaying.Marking);
            CollectionAssert.AreEquivalent(new[] { jean }, customerOut.Marking);

            simulator.SimulateStep();
            CollectionAssert.IsEmpty(customerAtEntrance.Marking);
            CollectionAssert.IsEmpty(customerWaiting.Marking);
            CollectionAssert.IsEmpty(cutting.Marking);
            CollectionAssert.AreEquivalent(new Person[] { joe }, idle.Marking);
            CollectionAssert.AreEquivalent(new Person[] { daniel }, customerPaying.Marking);
            CollectionAssert.IsEmpty(customerNotPaying.Marking);
            CollectionAssert.AreEquivalent(new[] { jean }, customerOut.Marking);

            simulator.SimulateStep();
            CollectionAssert.IsEmpty(customerAtEntrance.Marking);
            CollectionAssert.IsEmpty(customerWaiting.Marking);
            CollectionAssert.IsEmpty(cutting.Marking);
            CollectionAssert.AreEquivalent(new Person[] { joe }, idle.Marking);
            CollectionAssert.IsEmpty(customerPaying.Marking);
            CollectionAssert.IsEmpty(customerNotPaying.Marking);
            CollectionAssert.AreEquivalent(new[] { jean, daniel }, customerOut.Marking);

            // No more move
            simulator.SimulateStep();
            CollectionAssert.IsEmpty(customerAtEntrance.Marking);
            CollectionAssert.IsEmpty(customerWaiting.Marking);
            CollectionAssert.IsEmpty(cutting.Marking);
            CollectionAssert.AreEquivalent(new Person[] { joe }, idle.Marking);
            CollectionAssert.IsEmpty(customerPaying.Marking);
            CollectionAssert.IsEmpty(customerNotPaying.Marking);
            CollectionAssert.AreEquivalent(new[] { jean, daniel }, customerOut.Marking);
        }
Example #11
0
        /// <summary>
        /// Goes through the steps of the (improved) HeuristicMiner Algorithm:
        /// Find starting-events => build adjacency-matrix => convert into petrinet
        /// </summary>
        /// <returns>A PetriNet as a ProcessModel</returns>
        /// <exception cref="ArgumentNullException">If the field-parameter is null.</exception>
        /// <author>Jannik Arndt</author>
        public ProcessModel Mine()
        {
            if (_field == null)
            {
                throw new Exception("The field parameter was null");
            }

            // Get parameters from MinerSettings
            var threshold = MinerSettings.GetAsDouble("AdjacencyThresholdSlider") / 100;
            var maxDepth  = MinerSettings.GetAsInt("MaximumRecursionDepthSlider");

            if (threshold < 0 || threshold > 1)
            {
                throw new Exception("Threshold must be between 0 and 1.");
            }
            if (maxDepth < 1)
            {
                throw new Exception("Maximum recursion depth must be more greater than 1.");
            }

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

            // 1. Create Adjacency Matrix
            var adjacencyMatrix = CreateAdjacencyMatrix(_field);

            // 2. Calculate the indexes of the first events
            var startindexes = GetColumnsWithOnlyNegativeEntries(adjacencyMatrix);

            // for every sub-processmodel
            foreach (var startindex in startindexes)
            {
                // 3. Create the dependency-Graph
                var rootNode = CreateDependencyGraph(_field.EventLog.ListOfUniqueEvents, adjacencyMatrix, threshold, 0.0, startindex, maxDepth);

                // 4. Turn the dependency-graph into a petri-net
                _listOfSubPetriNets.Add(CreatePetriNetFromDependencyGraph(rootNode, _field.EventLog, _field.Infotext));
            }

            // 5. Connect all Petrinets by one XOR-Split
            if (_listOfSubPetriNets.Count > 1)
            {
                // 5a. Connect all subnets to one start
                var startingPlace = _finalPetriNet.AddPlace("Start");
                foreach (var petriNet in _listOfSubPetriNets)
                {
                    var xorTransition = _finalPetriNet.AddTransition(incomingPlace: startingPlace);
                    _finalPetriNet.MergeWithPetriNet(petriNet, xorTransition);
                }
                // 5b. Add following transitions to all subnet-endings
                foreach (var openEndPlace in _finalPetriNet.GetSinks())
                {
                    if (openEndPlace.GetType() == typeof(Place))
                    {
                        _finalPetriNet.AddTransition(incomingPlace: (Place)openEndPlace);
                    }
                }
            }
            else
            {
                _finalPetriNet = _listOfSubPetriNets[0];
            }

            // 6. Connect all open endings
            _finalPetriNet = FixEnding(_finalPetriNet);

            // 7. Delete empty transitions
            _finalPetriNet = PetriNetOperation.CleanUpPetriNet(_finalPetriNet);

            // 8. Save information about the mining-process
            var processingTimeEnd = Process.GetCurrentProcess().TotalProcessorTime;
            var processingTime    = Math.Abs((processingTimeEnd - processingTimeStart).TotalMilliseconds) < 1 ? "< 15 ms" : (processingTimeEnd - processingTimeStart).TotalMilliseconds + " ms";

            _field.Information.Add("Processing Time", processingTime);
            _field.Information.Add("Number of Events", _finalPetriNet.Transitions.Count(s => s.IsLoop == false).ToString(CultureInfo.InvariantCulture));
            _field.Information.Add("Number of Transitions", _finalPetriNet.Transitions.Count.ToString(CultureInfo.InvariantCulture));
            _field.Information.Add("Number of Places", _finalPetriNet.Places.Count.ToString(CultureInfo.InvariantCulture));
            _field.Information.Add("Loops in the net", _finalPetriNet.CountLoops().ToString(CultureInfo.InvariantCulture));
            _field.Information.Add("Events used", _finalPetriNet.CountTransitionsWithoutANDs() - _finalPetriNet.CountLoops() + " of " + _field.EventLog.ListOfUniqueEvents.Count);
            _field.Information.Add("Parallel Models", startindexes.Count.ToString(CultureInfo.InvariantCulture));
            if (_listOfNodes.Count > 0)
            {
                _field.Information.Add("Minimal Adjacency", _listOfNodes.Min().ToString(CultureInfo.InvariantCulture));
                _field.Information.Add("Average Adjacency", Math.Round(_listOfNodes.Average(), 3).ToString(CultureInfo.InvariantCulture));
                if (Math.Abs(_listOfNodes.Min() - _listOfNodes.Average()) > 0.0001)
                {
                    _field.Information.Add("Standard Deviation", CalculateStandardDeviation(_listOfNodes).ToString(CultureInfo.InvariantCulture));
                }
            }

            return(_finalPetriNet);
        }
Example #12
0
        /// <summary>
        /// Adds a place and the transitions it leads to.
        /// </summary>
        /// <param name="startingTransition">>Contains the starting transition</param>
        /// <param name="followers">node.followers</param>
        /// <param name="petriNet">Contains the current petri net</param>
        /// <returns>The two transitions that are in an XOR-relation.</returns>
        /// <author>Jannik Arndt</author>
        public List <Transition> StartXOR(Transition startingTransition, List <EventNode> followers, PetriNet petriNet)
        {
            if (followers.Count > 1)
            {
                for (var index = 0; index < followers.Count; index++)
                {
                    _openParallelismCount.Push(Parallelism.Xor);
                }
            }

            var newPlace = petriNet.AddPlace();
            var listOfFollowingTransitions = new List <Transition>();

            foreach (var eventNode in followers)
            {
                if (eventNode == null)
                {
                    break;
                }

                /* _____________________          __________         ____________________________
                 * | startingTransition |  --->  ( NewPlace )  --->  |  NewFollowingTransition  |
                 * '''''''''''''''''''''          **********         ''''''''''''''''''''''''''''
                 */
                var newFollowingTransition = petriNet.FindTransition(eventNode.InnerEvent.Name);
                // The following transition already exists => close something
                if (newFollowingTransition != null)
                {
                    if (_openParallelismCount.Count > 0)
                    {
                        switch (_openParallelismCount.Peek())
                        {
                        // Close XOR
                        case Parallelism.Xor:
                            newFollowingTransition.IncomingPlaces.Remove(newPlace);
                            startingTransition.AddOutgoingPlace(newFollowingTransition.IncomingPlaces.First());
                            _openParallelismCount.Pop();
                            break;

                        // Close AND
                        case Parallelism.And:
                            newFollowingTransition.AddIncomingPlace(newPlace);
                            startingTransition.AddOutgoingPlace(newPlace);
                            _openParallelismCount.Pop();
                            break;
                        }
                    }
                }
                // Open XOR
                else
                {
                    newFollowingTransition = petriNet.AddTransition(eventNode.InnerEvent.Name, incomingPlace: newPlace);
                    if (newPlace.IncomingTransitions.Count == 0)
                    {
                        startingTransition.AddOutgoingPlace(newPlace);
                    }
                }

                listOfFollowingTransitions.Add(newFollowingTransition);
            }
            if (newPlace.IncomingTransitions.Count == 0 && newPlace.OutgoingTransitions.Count == 0)
            {
                petriNet.Places.Remove(newPlace);
            }
            return(listOfFollowingTransitions);
        }
Example #13
0
        /// <summary>
        /// Creates and connects all places and transitions to a complete petri net
        /// </summary>
        /// <author>Christopher Licht</author>
        public void BuildTheNet()
        {
            Place Place;
            int   PlaceCounter = 0;

            //Create one place for all startActvities and one place for all endActvities
            Place StartPlace = _petriNet.AddPlace("start", 0);
            Place EndPlace   = _petriNet.AddPlace("end", 1);

            PlaceCounter = 1;

            //Create the transitions with the detected activities of step 1
            foreach (String CurrentActivity in _listOfActivities)
            {
                _petriNet.AddTransition(CurrentActivity);
            }

            //Connects all startActvities with the startPlace
            foreach (String CurrentStartActivity in _listOfStartActivities)
            {
                foreach (Transition CurrentTransition in _petriNet.Transitions)
                {
                    if (CurrentTransition.Name.Equals(CurrentStartActivity))
                    {
                        CurrentTransition.AddIncomingPlace(StartPlace);
                    }
                }
            }

            //Connects all endActvities with the endPlace
            foreach (String CurrentEndActivity in _listOfEndActivities)
            {
                foreach (Transition CurrentTransition in _petriNet.Transitions)
                {
                    if (CurrentTransition.Name.Equals(CurrentEndActivity))
                    {
                        CurrentTransition.AddOutgoingPlace(EndPlace);
                    }
                }
            }

            //All transitions get their incoming and outgoing places
            foreach (AlphaMinerPlaces CurrentAlphaMinerPlaces in _listOfAlphaPlaces)
            {
                PlaceCounter++;
                Place = _petriNet.AddPlace("", PlaceCounter);

                //Splits the predecessor and followers of the current place
                HashSet <String> _ListOfPredecessor = CurrentAlphaMinerPlaces.PredecessorHashSet;
                HashSet <String> _ListOfFollower    = CurrentAlphaMinerPlaces.FollowerHashSet;

                //The current predecessor-transition will be connected to the current place
                for (int i = 0; i < _ListOfPredecessor.Count; i++)
                {
                    foreach (Transition CurrentTransition in _petriNet.Transitions)
                    {
                        if (CurrentTransition.Name.Equals(_ListOfPredecessor.ElementAt(i)))
                        {
                            CurrentTransition.AddOutgoingPlace(Place);
                        }
                    }
                }

                //The current follower-transition will be connected to the current place
                for (int i = 0; i < _ListOfFollower.Count; i++)
                {
                    foreach (Transition CurrentTransition in _petriNet.Transitions)
                    {
                        if (CurrentTransition.Name.Equals(_ListOfFollower.ElementAt(i)))
                        {
                            CurrentTransition.AddIncomingPlace(Place);
                        }
                    }
                }
            }
        }