/// <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 }); }
/// <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); }
/// <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 }); }
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 }); }
/// <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> /// 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); }
/// <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); }
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 }
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); }
/// <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); }
/// <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); }
/// <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); } } } } }