/// <summary> /// Adds all added Transition to the NetWithDifference /// </summary> /// <author>Jannik Arndt,Thomas Meents</author> public void AddAddedTransitions(PetriNet netWithDifference) { // Find all Transitions that have the DiffStatus "added" List<Transition> addedTransitions = ListOfChoosenProcessModels[1].Transitions.Where(transition => transition.DiffStatus == DiffState.Added).ToList(); foreach (Transition addedTransition in addedTransitions) { netWithDifference.Places.AddRange(addedTransition.OutgoingPlaces); addedTransition.DiffStatus = DiffState.Added; // For non-starting transitions if (addedTransition.IncomingPlaces[0].IncomingTransitions != null && addedTransition.IncomingPlaces[0].IncomingTransitions.Count > 0) { List<Transition> listOfFollower = new List<Transition>(); if (addedTransition.OutgoingPlaces[0].OutgoingTransitions.Count > 0) { foreach (Place t in addedTransition.OutgoingPlaces) foreach (Transition newfollower in t.OutgoingTransitions) if (!listOfFollower.Contains(newfollower)) listOfFollower.Add(newfollower); } else { Transition follower = new Transition(); listOfFollower.Add(follower); } if (listOfFollower.Count > 0) { listOfFollower[0].IncomingPlaces.Add(addedTransition.OutgoingPlaces[0]); } else { Place endPlace = new Place("End"); addedTransition.OutgoingPlaces.Add(endPlace); } } // For starting Transitions else { foreach (Place t in addedTransition.OutgoingPlaces) { if (t.OutgoingTransitions.Count <= 0) continue; addedTransition.IncomingPlaces[0].Name = "Start"; netWithDifference.Places.Add(addedTransition.IncomingPlaces[0]); if (addedTransition.IncomingPlaces[0].OutgoingTransitions.Count > 1) addedTransition.IncomingPlaces[0].OutgoingTransitions.RemoveAt(1); if (addedTransition.OutgoingPlaces[0].IncomingTransitions.Count > 1) addedTransition.OutgoingPlaces[0].IncomingTransitions.RemoveAt(1); netWithDifference.Places.RemoveAt(0); } } netWithDifference.Transitions.Add(addedTransition); } }
public void TransitionTest() { Transition testTransition = new Transition(); Assert.IsNotNull(testTransition.IncomingPlaces); Assert.IsNotNull(testTransition.OutgoingPlaces); Assert.IsFalse(testTransition.IsLoop); Assert.IsFalse(testTransition.IsANDJoin); Assert.IsFalse(testTransition.IsANDSplit); }
public void EqualsTest() { var transition1 = new Transition("Test"); var transition2 = new Transition("Test"); var comparer = new TransitionComparer(); Assert.IsTrue(comparer.Equals(transition1, transition2)); Assert.IsTrue(comparer.Equals(transition1, transition1)); Assert.IsFalse(comparer.Equals(transition1, null)); Assert.IsFalse(comparer.Equals(transition2, null)); }
public void GetHashCodeTest() { var transition = new Transition("Test"); var comparer = new TransitionComparer(); var expected = "Test".GetHashCode(); var actual = comparer.GetHashCode(transition); Assert.AreEqual(expected, actual); actual = comparer.GetHashCode(null); Assert.AreEqual(0, actual); }
public void OutgoingANDTransitionsTest() { Place testPlace = new Place(); Transition t1 = new Transition("t1"); Transition t2 = new Transition("t2"); t1.IsANDJoin = true; t2.IsANDSplit = true; testPlace.OutgoingTransitions.Add(t1); testPlace.OutgoingTransitions.Add(t2); List<Transition> result = testPlace.OutgoingANDTransitions; Assert.IsTrue(result.Contains(t1)); Assert.IsTrue(result.Contains(t2)); }
/// <summary> /// This method creates a petri net with five places and four transitions. /// </summary> /// <autor>Markus Holznagel</autor> public static PetriNet PetriNetWithFivePlacesAndFourTransitions() { PetriNet petriNet = new PetriNet("Petri-Net Name"); Place pAIn = new Place("PlaceAIn", 0); Place pAOut = new Place("PlaceAOut", 0); Place pBOut = new Place("PlaceBOut", 0); Place pCOut = new Place("PlaceCOut", 0); Place pDOut = new Place("PlaceDOut", 0); Transition tA = new Transition("TransitionA"); Transition tB = new Transition("TransitionB"); Transition tC = new Transition("TransitionC"); Transition tD = new Transition("TransitionD"); pAIn.AppendOutgoingTransition(tA); pAOut.AppendOutgoingTransition(tB); pBOut.AppendOutgoingTransition(tC); pCOut.AppendOutgoingTransition(tD); tA.AddOutgoingPlace(pAOut); tB.AddOutgoingPlace(pBOut); tC.AddOutgoingPlace(pCOut); tD.AddOutgoingPlace(pDOut); // Create petri net petriNet.Places.Add(pAIn); petriNet.Places.Add(pAOut); petriNet.Places.Add(pBOut); petriNet.Places.Add(pCOut); petriNet.Places.Add(pDOut); petriNet.Transitions.Add(tA); petriNet.Transitions.Add(tB); petriNet.Transitions.Add(tC); petriNet.Transitions.Add(tD); return petriNet; }
/// <summary> /// Adds an outgoing transition to the place. This is usually called when you add a <see cref="Transition"/> to the net. /// </summary> /// <param Name="transition">The outgoing transition.</param> public void AppendOutgoingTransition(Transition transition) { if (!OutgoingTransitions.Contains(transition)) OutgoingTransitions.Add(transition); }
/// <summary> /// Draws the transition with the incoming and outgoing places. /// </summary> /// <param name="node">Node that will be drawn</param> /// <param name="relayed">Relayed place. It will be the incoming place of the transition</param> /// <param name="overwriteOutgoingPlace">optional place that will be overwrite the outgoingplace</param> /// <param name="overwriteIncomingPlace">optional place that will be overwrite the Incomingplace</param> /// <returns>Outgoing Place of the drawn Transition</returns> /// <author>Thomas Meents</author> private Place DrawLeafPetrinet(InductiveMinerTreeNode node, Place relayed, Place overwriteOutgoingPlace = null, Place overwriteIncomingPlace = null) { if (!node.Operation.Equals(OperationsEnum.isLeaf)) throw new Exception("Only leafs can be drawn."); Place outgoing = new Place(); IMPetriNet.Places.Add(outgoing); if (overwriteIncomingPlace != null) relayed = overwriteIncomingPlace; Transition transition = new Transition(node.Event.Name) { IsDrawn = false }; transition.AddIncomingPlace(relayed); transition.AddOutgoingPlace(outgoing); if (overwriteOutgoingPlace != null) { transition.OutgoingPlaces.Remove(outgoing); transition.OutgoingPlaces.Add(overwriteOutgoingPlace); } IMPetriNet.Transitions.Add(transition); return outgoing; }
/// <summary> /// Recursively moves threw the tree and generates the IMPetrinet /// </summary> /// <param name="node">actual node</param> /// <param name="relayedPlace">Place that the process operator get</param> /// <param name="relayedOutgoingPlace">optional place that will be overwrite the outgoingplace</param> /// <param name="relayedIncomingPlace">optional place that will be overwrite the incomingplace</param> /// <author>Thomas Meents, Bernd Nottbeck</author> private Place TraverseTreePetrinet(InductiveMinerTreeNode node, Place relayedPlace, Place relayedOutgoingPlace = null, Place relayedIncomingPlace = null) { if (node.Operation.Equals(OperationsEnum.isLeaf)) { return DrawLeafPetrinet(node, relayedPlace, overwriteIncomingPlace: relayedIncomingPlace, overwriteOutgoingPlace: relayedOutgoingPlace); } if (node.Operation.Equals(OperationsEnum.isSequence)) { if (node.LeftLeaf != null) { Place temp = TraverseTreePetrinet(node.LeftLeaf, relayedPlace); if (node.RightLeaf != null) temp = TraverseTreePetrinet(node.RightLeaf, temp); return temp; } } else if (node.Operation.Equals(OperationsEnum.isXOR)) { if (node.LeftLeaf != null) { Place tempXORExitPlace = TraverseTreePetrinet(node.LeftLeaf, relayedPlace); if (node.RightLeaf == null) return null; Place newPlace = TraverseTreePetrinet(node.RightLeaf, tempXORExitPlace, relayedIncomingPlace: relayedPlace, relayedOutgoingPlace: tempXORExitPlace); if (tempXORExitPlace != null) return tempXORExitPlace; return newPlace; } } else if (node.Operation.Equals(OperationsEnum.isLoop)) { Place tempLoopEntrancePlace = relayedPlace; if (node.LeftLeaf != null) { Place temp = TraverseTreePetrinet(node.LeftLeaf, relayedPlace); Place tempLoopExitPlace = temp; if (node.RightLeaf != null) { //prevents a Nullpointer-Exception if the first Place is a Loop. if (tempLoopEntrancePlace != IMPetriNet.Places[0]) { temp = TraverseTreePetrinet(node.RightLeaf, temp); IMPetriNet.AddTransition("Loop", incomingPlace: temp, outgoingPlace: tempLoopEntrancePlace, isLoop: true); } else { temp = TraverseTreePetrinet(node.RightLeaf, temp, relayedOutgoingPlace: tempLoopEntrancePlace); if (tempLoopExitPlace != null) temp = tempLoopExitPlace; } } return temp; } } else if (node.Operation.Equals(OperationsEnum.isParallel)) { Transition ANDSplit = new Transition("AND-Split"); ANDSplit.AddIncomingPlace(relayedPlace); IMPetriNet.Transitions.Add(ANDSplit); Place NewPlaceLeft = new Place(); Place NewPlaceRight = new Place(); IMPetriNet.Places.Add(NewPlaceLeft); IMPetriNet.Places.Add(NewPlaceRight); ANDSplit.AddOutgoingPlace(NewPlaceLeft); ANDSplit.AddOutgoingPlace(NewPlaceRight); Transition ANDJoin = new Transition("AND-Join"); Place AndJoinOutgoingPlace = new Place(); ANDJoin.AddOutgoingPlace(AndJoinOutgoingPlace); IMPetriNet.Places.Add(AndJoinOutgoingPlace); IMPetriNet.Transitions.Add(ANDJoin); if (node.LeftLeaf != null) { Place temp = TraverseTreePetrinet(node.LeftLeaf, relayedPlace, relayedIncomingPlace: NewPlaceLeft); ANDJoin.AddIncomingPlace(temp); if (node.RightLeaf != null) { temp = TraverseTreePetrinet(node.RightLeaf, NewPlaceRight); ANDJoin.AddIncomingPlace(temp); } return AndJoinOutgoingPlace; } } else { throw new Exception("Something in the process tree is wrong."); } return relayedPlace; }
/// <summary> /// This method creates a petri net with one loop, three places and four transitions. /// </summary> /// <autor>Thomas Meents</autor> public static PetriNet PetriNetWithOneLoopThreePlacesAndThreeTransitions() { PetriNet PetriNet = new PetriNet("Petri-Net Name"); Place paIn = new Place("PlaceAIn", 0); Place paOut = new Place("PlaceAOut", 0); Place pbOut = new Place("PlaceBOut", 0); Transition ta = new Transition("TransitionA"); Transition tb = new Transition("TransitionB"); Transition tc = new Transition(""); tb.IsLoop = true; //loop paIn.AppendOutgoingTransition(ta); paOut.AppendOutgoingTransition(tb); paOut.AppendIncomingTransition(tb); //loop pbOut.AppendOutgoingTransition(tc); pbOut.AppendOutgoingTransition(tb); //loop ta.AddOutgoingPlace(paOut); tb.AddOutgoingPlace(pbOut); tb.AddIncomingPlace(paIn); //loop PetriNet.Places.Add(paIn); PetriNet.Places.Add(paOut); PetriNet.Places.Add(pbOut); PetriNet.Transitions.Add(ta); PetriNet.Transitions.Add(tb); PetriNet.Transitions.Add(tc); return PetriNet; }
/// <summary> /// Adds another PetriNet to this at the given Transition (since the other PetriNet should start with a place). /// Keep in mind to close all open sinks afterwards! /// </summary> /// <param name="petriNet">The other PetriNet</param> /// <param name="atTransition">A transition in THIS PetriNet, where the added net will be connected</param> /// <author>Jannik Arndt</author> public void MergeWithPetriNet(PetriNet petriNet, Transition atTransition) { List<Node> sources = petriNet.GetSources(); if (sources.Count > 0) { atTransition.OutgoingPlaces.Add((sources[0] as Place)); atTransition.OutgoingPlaces[0].AppendIncomingTransition(atTransition); Transitions.AddRange(petriNet.Transitions); Places.AddRange(petriNet.Places); } }
/// <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); }
/// <summary> /// Adds a place and connects the open transitions to it. Then puts the given transition behind that whole thing. /// </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 empty transition after the place that combines to XOR.</returns> /// <author>Jannik Arndt</author> public List<Transition> EndXOR(List<Transition> startingTransition, PetriNet petriNet, Transition endingTransition = null) { if (endingTransition == null) endingTransition = petriNet.AddTransition(); if (_openParallelismCount.Count > 0) _openParallelismCount.Pop(); var newPlace = petriNet.AddPlace(); foreach (var transition in startingTransition) transition.AddOutgoingPlace(newPlace); endingTransition.AddIncomingPlace(newPlace); return new List<Transition> { endingTransition }; }
/// <summary> /// Checks the parallelism of two transitions in a given petri net /// </summary> /// <param name="transition1">A Transition</param> /// <param name="transition2">Another Transition</param> /// <param name="petriNet">Petrinet</param> /// <param name="level"></param> /// <returns>Returns true if the two transitions are parallel</returns> /// <autor>Andrej Albrecht</autor> private static bool CheckTransitionIsParallel(Transition transition1, Transition transition2, PetriNet petriNet, int level = 0) { //return false if the level is to large and unreal to prevent a stackoverflow exception if (level > petriNet.Transitions.Count + petriNet.Places.Count) return false; //Same Transition is at the first call never parallel! if (level == 0 && transition1.Name.Equals(transition2.Name)) return false; //long runtime: //The method CheckPathToTransitionAvailable can be improved: if ((transition1.IncomingPlaces.Count > 1 || transition2.IncomingPlaces.Count > 1) && (CheckPathToTransitionAvailable(transition1, transition2) || CheckPathToTransitionAvailable(transition2, transition1))) //The method CheckPathToTransitionAvailable find more branches and perhaps that two transitions are not parallel return false; foreach (Place incomingPlaceOfTransition1 in transition1.IncomingPlaces) { foreach (Place incomingPlaceOfTransition2 in transition2.IncomingPlaces) { if (incomingPlaceOfTransition1 == incomingPlaceOfTransition2) return false; //Here is the only position to return a false state! foreach (Transition incomingTransitionOfPlace1 in incomingPlaceOfTransition1.IncomingTransitions) { foreach (Transition incomingTransitionOfPlace2 in incomingPlaceOfTransition2.IncomingTransitions) if (incomingTransitionOfPlace1.IsLoop || incomingTransitionOfPlace1.Name.Equals(incomingTransitionOfPlace2.Name) || CheckTransitionIsParallel(incomingTransitionOfPlace2, incomingTransitionOfPlace2, petriNet, level + 1) || CheckTransitionIsParallel(transition1, incomingTransitionOfPlace2, petriNet, level + 1)) return true; if (CheckTransitionIsParallel(transition2, incomingTransitionOfPlace1, petriNet, level + 1)) return true; } } } return false; }
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> /// Checks if a path from a transition to another is available /// </summary> /// <param name="transition1">A Transition</param> /// <param name="transition2">Another Transition</param> /// <param name="depth">The current depth (The method set this value when it is calling itself)</param> /// <returns>Returns true if a path from a transition to another is available</returns> private static bool CheckPathToTransitionAvailable(Transition transition1, Transition transition2, int depth = 0) { if (depth > 5) return false; //beware StackOverflow if (transition1.Equals(transition2)) return true; foreach (Place pOutY in transition1.OutgoingPlaces) foreach (Transition pOutYtOut in pOutY.OutgoingTransitions) if (transition2.Equals(pOutYtOut) || CheckPathToTransitionAvailable(pOutYtOut, transition2, depth + 1)) return true; return false; }
/// <summary> /// This method creates a complex petri net with five places and eight transitions. /// </summary> /// <autor>Andrej Albrecht, Markus Holznagel</autor> public static PetriNet PetriNetWithFivePlacesAndEightTransitions() { 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); return petriNet; }
/// <summary> /// This method creates a complex petri net with six places and five transitions. /// </summary> /// <autor>Andrej Albrecht, Markus Holznagel</autor> public static PetriNet PetriNetWithSixPlacesAndFiveTransitions() { PetriNet petriNet = new PetriNet("Petri-Net Name"); Place pStart = new Place("Place Start", 0); Place p1 = new Place("c1", 0); Place p2 = new Place("c2", 0); Place p3 = new Place("c3", 0); Place p4 = new Place("c4", 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"); pStart.AppendOutgoingTransition(tA); tA.AddIncomingPlace(pStart); tA.AddOutgoingPlace(p1); tA.AddOutgoingPlace(p2); p1.AppendIncomingTransition(tA); p1.AppendOutgoingTransition(tB); p1.AppendOutgoingTransition(tC); p2.AppendIncomingTransition(tA); p2.AppendOutgoingTransition(tC); p2.AppendOutgoingTransition(tD); tB.AddIncomingPlace(p1); tB.AddOutgoingPlace(p3); tC.AddIncomingPlace(p1); tC.AddIncomingPlace(p2); tC.AddOutgoingPlace(p3); tC.AddOutgoingPlace(p4); tD.AddIncomingPlace(p2); tD.AddOutgoingPlace(p4); p3.AppendIncomingTransition(tB); p3.AppendIncomingTransition(tC); p3.AppendOutgoingTransition(tE); p4.AppendIncomingTransition(tC); p4.AppendIncomingTransition(tD); p4.AppendOutgoingTransition(tE); tE.AddIncomingPlace(p3); tE.AddIncomingPlace(p4); tE.AddOutgoingPlace(pEnd); pEnd.AppendIncomingTransition(tE); petriNet.Transitions.Add(tA); petriNet.Transitions.Add(tB); petriNet.Transitions.Add(tC); petriNet.Transitions.Add(tD); petriNet.Transitions.Add(tE); petriNet.Places.Add(pStart); petriNet.Places.Add(p1); petriNet.Places.Add(p2); petriNet.Places.Add(p3); petriNet.Places.Add(p4); petriNet.Places.Add(pEnd); return petriNet; }
/// <summary> /// Adds an incoming transition to the place. This is usually called when you add a <see cref="Transition"/> to the net. /// </summary> /// <param Name="transition">The incoming transition.</param> public void AppendIncomingTransition(Transition transition) { if (!IncomingTransitions.Contains(transition)) IncomingTransitions.Add(transition); }
/// <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; }
/// <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 }; }
/// <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> /// 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 a complex petri net with fourteen places and fourteen transitions. /// You can choose this for testing recursive parallelisms. /// </summary> /// <autor>Markus Holznagel</autor> public static PetriNet PetriNetWithFourteenPlacesAndFourteenTransitions() { PetriNet petriNet = new PetriNet("Petri-Net Name"); Place pStart = new Place("pStart"); Place p1 = new Place("p1"); Place p2 = new Place("p2"); Place p3 = new Place("p3"); Place p4 = new Place("p4"); Place p5 = new Place("p5"); Place p6 = new Place("p6"); Place p7 = new Place("p7"); Place p8 = new Place("p8"); Place p9 = new Place("p9"); Place p10 = new Place("p10"); Place p11 = new Place("p11"); Place p12 = new Place("p12"); Place pEnd = new Place("pEnd"); 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"); Transition tI = new Transition("I"); Transition tJ = new Transition("J"); Transition tK = new Transition("K"); Transition tL = new Transition("L"); Transition tM = new Transition("M"); Transition tN = new Transition("N"); // Transitions and Places pStart.AppendOutgoingTransition(tA); tA.AddIncomingPlace(pStart); tA.AddOutgoingPlace(p1); tA.AddOutgoingPlace(p2); p1.AppendIncomingTransition(tA); p1.AppendOutgoingTransition(tB); tB.AddIncomingPlace(p1); tB.AddOutgoingPlace(p3); tB.AddOutgoingPlace(p4); p2.AppendIncomingTransition(tA); p2.AppendOutgoingTransition(tC); tC.AddIncomingPlace(p2); tC.AddIncomingPlace(p5); tC.AddIncomingPlace(p6); p3.AppendIncomingTransition(tB); p3.AppendOutgoingTransition(tD); p3.AppendOutgoingTransition(tE); tD.AddIncomingPlace(p3); tD.AddOutgoingPlace(p7); tE.AddIncomingPlace(p3); tE.AddOutgoingPlace(p7); p4.AppendIncomingTransition(tB); p4.AppendOutgoingTransition(tF); p4.AppendOutgoingTransition(tG); tF.AddIncomingPlace(p4); tF.AddOutgoingPlace(p8); tG.AddIncomingPlace(p4); tG.AddOutgoingPlace(p8); p5.AppendIncomingTransition(tC); p5.AppendOutgoingTransition(tH); p5.AppendOutgoingTransition(tI); tH.AddIncomingPlace(p5); tH.AddOutgoingPlace(p9); tI.AddIncomingPlace(p5); tI.AddOutgoingPlace(p9); p6.AppendIncomingTransition(tC); p6.AppendOutgoingTransition(tJ); p6.AppendOutgoingTransition(tK); tJ.AddIncomingPlace(p6); tJ.AddOutgoingPlace(p10); tK.AddIncomingPlace(p6); tK.AddOutgoingPlace(p10); p7.AppendIncomingTransition(tD); p7.AppendIncomingTransition(tE); p7.AppendOutgoingTransition(tL); p8.AppendIncomingTransition(tF); p8.AppendIncomingTransition(tG); p8.AppendOutgoingTransition(tL); tL.AddIncomingPlace(p7); tL.AddIncomingPlace(p8); tL.AddOutgoingPlace(p11); p9.AppendIncomingTransition(tH); p9.AppendIncomingTransition(tI); p9.AppendOutgoingTransition(tM); p10.AppendIncomingTransition(tJ); p10.AppendIncomingTransition(tK); p10.AppendOutgoingTransition(tM); tM.AddIncomingPlace(p9); tM.AddIncomingPlace(p10); tM.AddOutgoingPlace(p12); p11.AppendIncomingTransition(tL); p11.AppendOutgoingTransition(tN); p12.AppendIncomingTransition(tM); p12.AppendOutgoingTransition(tN); tN.AddIncomingPlace(p11); tN.AddIncomingPlace(p12); tN.AddOutgoingPlace(pEnd); pEnd.AppendIncomingTransition(tN); // Add Transitions and places to petrinet 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.Transitions.Add(tI); petriNet.Transitions.Add(tJ); petriNet.Transitions.Add(tK); petriNet.Transitions.Add(tL); petriNet.Transitions.Add(tM); petriNet.Transitions.Add(tN); petriNet.Places.Add(pStart); petriNet.Places.Add(p1); petriNet.Places.Add(p2); petriNet.Places.Add(p3); petriNet.Places.Add(p4); petriNet.Places.Add(p5); petriNet.Places.Add(p6); petriNet.Places.Add(p7); petriNet.Places.Add(p8); petriNet.Places.Add(p9); petriNet.Places.Add(p10); petriNet.Places.Add(p11); petriNet.Places.Add(p12); petriNet.Places.Add(pEnd); return petriNet; }
/// <summary> /// Resolves a construct of three parallel events: a AND ( b XOR c ) /// </summary> /// <param name="event1">One event</param> /// <param name="a">An event node</param> /// <param name="b">An event node</param> /// <param name="c">An event node</param> /// <param name="petriNet">Current petri net</param> /// <returns>A list with final transitions</returns> /// <author>Jannik Arndt</author> public List<Transition> StartAand_BxorC(Transition event1, EventNode a, EventNode b, EventNode c, PetriNet petriNet) { var finalTransition = petriNet.AddTransition("AND Join"); finalTransition.IsANDJoin = true; var andTransition = StartAND(event1, new List<EventNode> { a }, petriNet); EndAND(andTransition, petriNet, finalTransition); var xorTransition = StartXOR(event1, new List<EventNode> { b, c }, petriNet); EndXOR(xorTransition, petriNet, finalTransition); return new List<Transition> { finalTransition }; }
/// <summary> /// Draw a Rectangle /// </summary> /// <param name="transition"></param> /// <autor>Thomas Meents, Krystian Zielonka</autor> private ExtendedThumb DrawTransition(Transition transition) { String name = transition.Name.Trim(); ExtendedThumb transitionThumb = new ExtendedThumb { Name = "Transition", Width = Settings.Default.TransitionWidth, Height = Settings.Default.TransitionHeight }; transitionThumb.Margin = new Thickness(-transitionThumb.Width/2, -transitionThumb.Height/2, 0, 0); transitionThumb.Template = GetTransitionTemplate(); transitionThumb.ToolTip = name; transitionThumb.SetValue(ContentControl.ContentProperty, name); ContextMenu contextMenu = new ContextMenu(); Label labelText = new Label {Content = name}; contextMenu.Items.Add(labelText); transitionThumb.ContextMenu = contextMenu; return transitionThumb; }
/// <summary> /// Resolves a construct of three parallel events: a XOR ( b AND c ) /// </summary> /// <param name="event1">Event number one</param> /// <param name="a">An Event node</param> /// <param name="b">An Event node</param> /// <param name="c">An Event node</param> /// <param name="petriNet">The current petri net</param> /// <returns>A list with final transition</returns> /// <author>Jannik Arndt</author> public List<Transition> StartAxor_BandC(Transition event1, EventNode a, EventNode b, EventNode c, PetriNet petriNet) { var finalTransition = petriNet.AddTransition(); // empty transition, will possibly be cleaned up finalTransition.Name = FindFirstCommonSuccessor(new List<EventNode> { a, b, c }); var xorTransition = StartXOR(event1, new List<EventNode> { a }, petriNet); EndXOR(xorTransition, petriNet, finalTransition); var andSplit = petriNet.AddTransition(); // no idea where this disappears... andSplit.AddIncomingPlace(xorTransition[0].IncomingPlaces[0]); // XOR-Split-Place var andTransition = StartAND(andSplit, new List<EventNode> { b, c }, petriNet); var andJoin = petriNet.AddTransition("AND Join"); andJoin.IsANDJoin = true; var andTransition2 = EndAND(andTransition, petriNet, andJoin); andTransition2[0].AddOutgoingPlace(finalTransition.IncomingPlaces.FirstOrDefault()); return new List<Transition> { finalTransition }; }
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> /// 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> /// Returns a generated TransitionID /// </summary> /// <param name="transition"></param> /// <returns></returns> /// <autor>Andrej Albrecht</autor> public String GetTransitionID(Transition transition) { return "t" + Transitions.IndexOf(transition); }