/// <summary>
        /// Checks the parallelism of two transitions in a petrinet recursively
        /// In some petrinets with a high complexity
        /// </summary>
        /// <param name="transition1">Eventname of y-direction</param>
        /// <param name="transition2">Eventname of x-direction</param>
        /// <param name="petriNet">Petrinet</param>
        /// <returns>Return true if the two transitions are parallel</returns>
        /// <autor>Andrej Albrecht</autor>
        // ReSharper disable once UnusedMember.Local
        private static bool CheckTransitionIsParallel(string transition1, string transition2, PetriNet petriNet)
        {
            Transition transitionY = petriNet.FindTransition(transition1);
            Transition transitionX = petriNet.FindTransition(transition2);

            return(CheckTransitionIsParallel(transitionY, transitionX, petriNet));
        }
        /// <summary>
        /// Create a footprint for a petrinet
        /// </summary>
        /// <param name="petriNet">Petrinet</param>
        /// <returns>returns a ComparingFootprint</returns>
        /// <autor>Andrej Albrecht</autor>
        public static ComparingFootprint CreateFootprint(PetriNet petriNet)
        {
            ComparingFootprint resultFootprint = new ComparingFootprint(new CellType[petriNet.Transitions.Count, petriNet.Transitions.Count]);

            foreach (Transition transition in petriNet.Transitions)
            {
                if (!transition.IsLoop)
                {
                    resultFootprint.AddEventHeader(transition.Name);
                }
            }

            List <String> transitionLoops = Transition.GetTransitionLoops(petriNet);

            int indexRow = 0;

            foreach (String headerNameRow in resultFootprint.HeaderWithEventNames)
            {
                int indexColumn = 0;
                foreach (String headerNameColumn in resultFootprint.HeaderWithEventNames)
                {
                    CellType transitionRelationship = GetTransitionRelationship(headerNameRow, headerNameColumn, petriNet);

                    //reset the cellstate to nothing, if the cell have no state:
                    resultFootprint.ResultMatrix[indexRow, indexColumn] = CellType.Nothing;

                    //save the found transition relationship to the cell and check parallelism with method checkTransitionParallel:
                    if (headerNameRow.Equals(headerNameColumn) && transitionLoops.Contains(headerNameColumn))
                    {
                        resultFootprint.ResultMatrix[indexRow, indexColumn] = CellType.Loop;
                    }
                    else if (transitionRelationship.Equals(CellType.Parallel))
                    {
                        resultFootprint.ResultMatrix[indexRow, indexColumn] = CellType.Parallel;

                        if (indexRow != indexColumn)
                        {
                            resultFootprint.ResultMatrix[indexColumn, indexRow] = CellType.Parallel;
                        }
                    }
                    else if (transitionRelationship.Equals(CellType.Right))
                    {
                        if (resultFootprint.ResultMatrix[indexRow, indexColumn].Equals(CellType.Left))
                        {
                            resultFootprint.ResultMatrix[indexRow, indexColumn] = CellType.Parallel;
                        }

                        resultFootprint.ResultMatrix[indexRow, indexColumn] = CellType.Right;

                        if (indexRow != indexColumn)
                        {
                            resultFootprint.ResultMatrix[indexColumn, indexRow] = CellType.Left;
                        }
                    }
                    else if (transitionRelationship.Equals(CellType.Left))
                    {
                        if (resultFootprint.ResultMatrix[indexRow, indexColumn].Equals(CellType.Right))
                        {
                            resultFootprint.ResultMatrix[indexRow, indexColumn] = CellType.Parallel;
                        }

                        resultFootprint.ResultMatrix[indexRow, indexColumn] = CellType.Left;
                    }

                    indexColumn++;
                }
                indexRow++;
            }
            return(resultFootprint);
        }
        /// <summary>
        /// The logic for finding the relationship between two transitions in a petrinet
        /// </summary>
        /// <param name="transitionOfColumn">Eventname of column</param>
        /// <param name="transitionOfRow">Eventname of row</param>
        /// <param name="petriNet">Petrinet</param>
        /// <autor>Andrej Albrecht</autor>
        private static CellType GetTransitionRelationship(string transitionOfColumn, string transitionOfRow, PetriNet petriNet)
        {
            if (CheckTransitionIsParallel(transitionOfColumn, transitionOfRow, petriNet))
            {
                return(CellType.Parallel);
            }

            //Transition        ->  Place               ->  Transition
            //transition  ->  outgoingPlaceOfTransition ->  outgoingTransitionofPlace
            foreach (Transition transition in petriNet.Transitions)
            {
                if (transition.Name.Equals(transitionOfColumn))
                {
                    foreach (Place outgoingPlaceOfTransition in transition.OutgoingPlaces)
                    {
                        foreach (Transition outgoingTransitionofPlace in outgoingPlaceOfTransition.OutgoingTransitions)
                        {
                            if (outgoingTransitionofPlace.Name.Equals(transitionOfRow))
                            {
                                return(CellType.Right);
                            }
                        }
                    }
                }
                else if (transition.Name.Equals(transitionOfRow))
                {
                    foreach (Place outgoingPlaceOfTransition in transition.OutgoingPlaces)
                    {
                        foreach (Transition outgoingTransitionofPlace in outgoingPlaceOfTransition.OutgoingTransitions)
                        {
                            if (outgoingTransitionofPlace.Name.Equals(transitionOfColumn))
                            {
                                return(CellType.Left);
                            }
                        }
                    }
                }
            }

            return(CellType.Nothing);
        }
Beispiel #4
0
    public void CreatePetriNet()
    {
        if (createdNet)
        {
            DestroyImmediate(pn);
        }

        if (pn == null)
        {
            pn = gameObject.AddComponent <PetriNet>();
        }


        createdNet = true;

        pn.CreateSlot("Tiro Recebido");   // 0
        pn.CreateSlot("Saúde");           // 1
        pn.CreateTransition("Atingido");  // T0
        pn.CreateTransition("Game Over"); // T1
        pn.CreateConnectionST(0, 0);
        pn.CreateConnectionST(1, 0);
        pn.CreateConnectionST(1, 1, 1, PetriNet.ConnectionType.Inhibitor);


        pn.CreateSlot("Quadrante Munição");      // 2
        pn.CreateSlot("Input Carregar Munição"); // 3
        pn.CreateSlot("Robo Vizinhança");        // 4
        pn.CreateSlot("Input Atacar");           // 5
        pn.CreateSlot("Munição");                // 6
        pn.CreateSlot("Tiro Enviado");           // 7
        pn.CreateTransition("Carregar Munição"); // T2
        pn.CreateTransition("Atacar Robo");      // T3
        pn.CreateConnectionST(2, 2);
        pn.CreateConnectionST(3, 2);
        pn.CreateConnectionST(4, 3);
        pn.CreateConnectionST(5, 3);
        pn.CreateConnectionST(6, 3);
        pn.CreateConnectionTS(6, 2, 10);
        pn.CreateConnectionTS(7, 3);

        pn.CreateSlot("Quadrante Colisão");          // 8
        pn.CreateSlot("Input Deslocar");             // 9
        pn.CreateSlot("Combustível");                // 10
        pn.CreateSlot("Input Carregar Combustível"); // 11
        pn.CreateSlot("Quadrante Combustível");      // 12
        pn.CreateTransition("Deslocar");             // T4
        pn.CreateTransition("Carregar Combustível"); // T5
        pn.CreateConnectionST(8, 4, 1, PetriNet.ConnectionType.Inhibitor);
        pn.CreateConnectionST(9, 4);
        pn.CreateConnectionST(10, 4);
        pn.CreateConnectionST(11, 5);
        pn.CreateConnectionST(12, 5);
        pn.CreateConnectionTS(10, 5, 20);

        pn.ListsToArrays();

        pn.AddTokensToSlot(1, 100);
        pn.AddTokensToSlot(6, 20);
        pn.AddTokensToSlot(10, 50);

        pn.transitionsArray[4].SetCallback(Move);
        pn.transitionsArray[1].SetCallback(Die);

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

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

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

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

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

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

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

            return(null);
        }
 public FullCoverageTreeBuilder(PetriNet petriNet)
     : base(petriNet)
 {
 }
        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);
        }
Beispiel #9
0
        public static (List <VPlace>, List <VTransition>, List <VArc>) FromOriginalModel(PetriNet net)
        {
            Dictionary <string, VPlace> places = new Dictionary <string, VPlace>();

            foreach (var netPlace in net.Places)
            {
                var vplace = new VPlace(netPlace.Position.x, netPlace.Position.y, netPlace.Tokens, netPlace.Id)
                {
                    Label = netPlace.Label,
                };
                places[netPlace.Id] = vplace;
                vplace.BindSyncPlace(netPlace);
            }
            VPlace.Counter = places.Count + 1;

            Dictionary <string, VTransition> transitions = new Dictionary <string, VTransition>();

            foreach (var netTransition in net.Transitions)
            {
                var vtransition = new VTransition(netTransition.Position.x, netTransition.Position.y, netTransition.Id)
                {
                    Label    = netTransition.Label,
                    Priority = netTransition.Priority
                };
                transitions[netTransition.Id] = vtransition;
                vtransition.BindSyncTransition(netTransition);
            }

            VTransition.Counter = transitions.Count + 1;

            Dictionary <string, PetriNetNode> nodes = new Dictionary <string, PetriNetNode>();

            foreach (var kv in places)
            {
                nodes[kv.Key] = kv.Value;
            }

            foreach (var kv in transitions)
            {
                nodes[kv.Key] = kv.Value;
            }
            List <VArc> arcs = new List <VArc>();

            foreach (var netArc in net.Arcs)
            {
                var varc = new VArc();
                varc.IsDirected = true;
                varc.Id         = netArc.Id;
                varc.Weight     = netArc.Weight.ToString();
                varc.From       = nodes[netArc.NodeFrom.Id];
                varc.To         = nodes[netArc.NodeTo.Id];
                varc.From.ThisArcs.Add(varc);
                varc.To.ThisArcs.Add(varc);
                arcs.Add(varc);
                varc.BindSyncArc(netArc);
            }

            return(places.Select(t => t.Value).ToList(), transitions.Select(t => t.Value).ToList(), arcs);
        }
Beispiel #10
0
        /// <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);
        }
Beispiel #11
0
 public PetriNetModule(PetriNet petriNet)
 {
     PetriNet = petriNet;
 }
Beispiel #12
0
        /// <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);
        }
Beispiel #13
0
        /// <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);
        }
Beispiel #14
0
        public void Process(PetriNet petriNet)
        {
            if (this.Status != MarkingNodeStatus.Boundary)
                return;

            // Marking is dublicate
            if (this.Graph.GetVertex(v =>
                    this.Compare(v as MarkingTreeNode) == 0 &&
                    this.Value != v.Value &&
                    (v as MarkingTreeNode).Status != MarkingNodeStatus.Boundary) != null
            )
            {
                this.Status = MarkingNodeStatus.Dublicate;
                return;
            }

            // Marking is terminal
            Transition[] availableTransitions = petriNet.GetAvailableTransitions(this.Marking);
            if (availableTransitions.Length == 0)
            {
                this.Status = MarkingNodeStatus.Terminal;
                return;
            }

            foreach (MarkedTransition transition in availableTransitions)
            {
                (this.Tree as MarkingTree).AddMarking(petriNet.GetStateAfterExecute(this.Marking, transition), this.Value.ToString(), transition.Value.ToString());
            }
        }
        /// <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);
        }
Beispiel #16
0
        public PetriNet Compile(PetriNet phylum)
        {
            String prefix = phylum.ActivityCount + ".internal.";

            Place p1 = phylum.NewPlace(prefix + "initialized");
            Place p2 = phylum.NewPlace(prefix + "closed");

            if (startNode == null)
            {
                // New Activity
                phylum.ActivityCount += 1;
                int currentID = phylum.ActivityCount;
                // Compile
                new Empty().Compile(phylum);
                // Merge
                phylum.Merge(p1, currentID + ".internal.initialized");
                phylum.Merge(p2, currentID + ".internal.closed");

                return(phylum);
            }

            // Create Steps
            foreach (FlowNode node in steps)
            {
                if (node is FlowStep)
                {
                    FlowStep step       = (FlowStep)node;
                    String   prefixStep = prefix + step.Id + ".";

                    Place stp1 = phylum.NewPlace(prefixStep + "start");
                    Place stp2 = phylum.NewPlace(prefixStep + "next");

                    phylum.ActivityCount += 1;
                    int currentID = phylum.ActivityCount;
                    // Action Activity
                    step.Action.Compile(phylum);
                    // Connect
                    phylum.Merge(stp1, currentID + ".internal.initialized");
                    phylum.Merge(stp2, currentID + ".internal.closed");
                }
                else if (node is FlowDecision)
                {
                    FlowDecision dec        = (FlowDecision)node;
                    String       prefixStep = prefix + dec.Id + ".";

                    Place      dp1           = phylum.NewPlace(prefixStep + "start");
                    Place      condition     = phylum.NewPlace(prefixStep + "condition");
                    Place      right         = phylum.NewPlace(prefixStep + "true");
                    Place      wrong         = phylum.NewPlace(prefixStep + "false");
                    Transition evalCondition = phylum.NewTransition(prefixStep + "evalcondition");
                    Transition startTrue     = phylum.NewTransition(prefixStep + "starttrue");
                    Transition startFalse    = phylum.NewTransition(prefixStep + "startfalse");
                    // Connect
                    phylum.NewArc(dp1, evalCondition);
                    phylum.NewArc(evalCondition, condition);
                    phylum.NewArc(condition, startTrue);
                    phylum.NewArc(condition, startFalse);
                    phylum.NewArc(startTrue, right);
                    phylum.NewArc(startFalse, wrong);
                }
                else if (node is FlowSwitch)
                {
                    FlowSwitch swtch      = (FlowSwitch)node;
                    String     prefixStep = prefix + swtch.Id + ".";

                    Place sp1      = phylum.NewPlace(prefixStep + "start");
                    Place sdefault = phylum.NewPlace(prefixStep + "default");

                    // Inner Petri Net
                    Place lastState = sp1;

                    for (int i = 1; i <= swtch.Branches.Count + 1; i++)
                    {
                        if (i <= swtch.Branches.Count)
                        {
                            Place      cond     = phylum.NewPlace(prefixStep + "condition" + i);
                            Place      state    = phylum.NewPlace(prefixStep + "case" + i);
                            Transition evalCase = phylum.NewTransition(prefixStep + "evalcase" + i);
                            Transition initCase = phylum.NewTransition(prefixStep + "initcase" + i);
                            phylum.NewArc(lastState, evalCase);
                            phylum.NewArc(evalCase, cond);
                            phylum.NewArc(cond, initCase);
                            phylum.NewArc(initCase, state);
                            // LastState
                            lastState = cond;
                        }
                        else
                        {
                            Transition initDefault = phylum.NewTransition(prefixStep + "initdefault");
                            phylum.NewArc(lastState, initDefault);
                            phylum.NewArc(initDefault, sdefault);
                        }
                    }
                }
            }
            // Merge
            // StartNode
            phylum.Merge(p1, prefix + steps.First(e => e.Id.Equals(startNode)).Id + ".start");

            foreach (FlowNode node in steps)
            {
                if (node is FlowStep)
                {
                    FlowStep step       = (FlowStep)node;
                    String   prefixStep = prefix + step.Id + ".";

                    if (step.Next != null)
                    {
                        phylum.Merge(prefixStep + "next", prefix + step.Next + ".start");
                    }
                    else
                    {
                        phylum.Merge(p2, prefixStep + "next");
                    }
                }
                else if (node is FlowDecision)
                {
                    FlowDecision dec            = (FlowDecision)node;
                    String       prefixDecision = prefix + dec.Id + ".";

                    if (dec.Right != null)
                    {
                        phylum.Merge(prefixDecision + "true", prefix + dec.Right + ".start");
                    }
                    else
                    {
                        phylum.Merge(p2, prefixDecision + "true");
                    }

                    if (dec.Wrong != null)
                    {
                        phylum.Merge(prefixDecision + "false", prefix + dec.Wrong + ".start");
                    }
                    else
                    {
                        phylum.Merge(p2, prefixDecision + "false");
                    }
                }
                else if (node is FlowSwitch)
                {
                    FlowSwitch swtch        = (FlowSwitch)node;
                    String     prefixSwitch = prefix + swtch.Id + ".";

                    //Default
                    if (swtch.Default != null)
                    {
                        phylum.Merge(prefixSwitch + "default", prefix + swtch.Default + ".start");
                    }
                    else
                    {
                        phylum.Merge(p2, prefixSwitch + "default");
                    }
                    // Branches
                    for (int i = 1; i <= swtch.Branches.Count; i++)
                    {
                        phylum.Merge(prefixSwitch + "case" + i, prefix + swtch.Branches[i - 1] + ".start");
                    }
                }
            }

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

            if (transitions == null)
            {
                return;
            }

            foreach (var transition in transitions)
            {
                foreach (var eventNode in node.ListOfFollowers)
                {
                    if (transition.Name == eventNode.InnerEvent.Name || transition.IsANDJoin)
                    {
                        HandleNodesAndCloseParallelisms(transition, eventNode, log, petriNet);
                    }
                }
            }
        }
Beispiel #18
0
        /// <summary>
        /// Compute optimal alignment based on a trace and a Petri net
        /// </summary>
        /// <param name="trace">Workflow trace</param>
        /// <param name="pNet">Petri net</param>
        /// <param name="traceMoveCost">Trace move cost</param>
        /// <param name="modelMoveCost">Model move cost</param>
        /// <returns>Alignment on trace</returns>
        public static List <STransition> OptimalAlignmentOnTrace(WorkflowTrace trace, PetriNet pNet, int traceMoveCost = 1,
                                                                 int modelMoveCost = 1)
        {
            var tracePNet = MakePNetFromTrace(trace);
            var syncNet   = new SynchronousProductNet(tracePNet, pNet, traceMoveCost, modelMoveCost);

            return(FindOptimalAlignment(syncNet));
        }
Beispiel #19
0
 public PropertiesChecker(PetriNet petriNet)
 {
     _petriNet = petriNet;
     _coverageTreeBuilder = new CoverageTreeBuilder(_petriNet);
     _fullCoverageTreeBuilder  = new FullCoverageTreeBuilder(_petriNet);
 }
 public PNAssertionDeadLock(PetriNet processDef) : base()
 {
     Process = processDef;
 }
Beispiel #21
0
        /// <summary>
        /// Обрабатывает все граничные вершины дерева
        /// </summary>
        /// <param name="petriNet">Сеть, по которой строится дерево</param>
        public void ProcessBoundaries(PetriNet petriNet)
        {
            MarkingTreeNode[] boundaries = this.GetBoundaries();

            if (boundaries.Length == 0)
                return;

            foreach (MarkingTreeNode node in boundaries)
            {
                node.Process(petriNet);
            }
            this.ProcessBoundaries(petriNet);
        }
        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 + ")");
            }
        }