public void AnalyzeCyclePetriNetTest()
        {
            // Arrange
            RelationMatrix originalMatrix = MakeCycleNetRelationMatrix();
            IPetriNet      originalNet    = MakeCycleNetPetriNet();

            // Act
            RelationMatrix matrix = PetriNetAnalyzer.MakeRelationMatrix(originalNet);

            // Assert
            Assert.AreEqual(5, matrix.Activities.Count);
            foreach (string act in matrix.Activities)
            {
                Assert.IsTrue(originalMatrix.Activities.Contains(act));
            }
            Assert.AreEqual(1, matrix.StartActivities.Count);
            Assert.IsTrue(matrix.StartActivities.Contains("a"));
            Assert.AreEqual(1, matrix.EndActivities.Count);
            Assert.IsTrue(matrix.EndActivities.Contains("e"));

            foreach (string actI in matrix.Activities)
            {
                foreach (string actJ in matrix.Activities)
                {
                    Assert.AreEqual(originalMatrix.Footprint[originalMatrix.ActivityIndices[actI], originalMatrix.ActivityIndices[actJ]],
                                    matrix.Footprint[matrix.ActivityIndices[actI], matrix.ActivityIndices[actJ]]);
                }
            }
        }
Exemple #2
0
        public void MakeEasyPetriNetTest()
        {
            // Arrange
            ImportedEventLog elog = CSVImport.MakeDataFrame(easyCsv);

            elog.SetActivity("act");
            elog.SetCaseId("id");
            WorkflowLog    wlog       = new WorkflowLog(elog);
            RelationMatrix matrix     = new RelationMatrix(wlog);
            IPetriNet      exampleNet = MakeEasyPetriNet();

            // Act
            IPetriNet madeNet = Alpha.MakePetriNet(matrix);

            // Assert
            Assert.IsNotNull(exampleNet);
            Assert.AreEqual(exampleNet.EndPlace.Id, madeNet.EndPlace.Id);
            Assert.AreEqual(exampleNet.StartPlace.Id, madeNet.StartPlace.Id);
            Assert.AreEqual(exampleNet.Places.Count, madeNet.Places.Count);
            Assert.AreEqual(exampleNet.Transitions.Count, madeNet.Transitions.Count);

            foreach (IPlace p in exampleNet.Places)
            {
                Assert.IsTrue(madeNet.Places.Exists(a => a.Id == p.Id));
            }
            foreach (ITransition t in exampleNet.Transitions)
            {
                Assert.IsTrue(madeNet.Transitions.Exists(a => a.Id == t.Id &&
                                                         a.Activity == t.Activity &&
                                                         a.InputPlaces.Count == t.InputPlaces.Count &&
                                                         a.OutputPlaces.Count == t.OutputPlaces.Count));
            }
        }
Exemple #3
0
        public void MakeEmptyPetriNetTest()
        {
            // Arrange
            List <string> activities = new List <string>()
            {
                "wake up", "have coffee", "have tea", "work", "go home", "go sleep", "play witcher"
            };
            HashSet <string> startActivities = new HashSet <string>()
            {
                "wake up"
            };
            HashSet <string> endActivities = new HashSet <string>()
            {
                "go sleep", "play witcher"
            };
            RelationMatrix matrix = new RelationMatrix(activities, startActivities, endActivities);

            // Act
            IPetriNet madeNet = Alpha.MakePetriNet(matrix);

            // Assert
            Assert.IsNotNull(madeNet);
            Assert.AreEqual("p1", madeNet.EndPlace.Id);
            Assert.AreEqual("p0", madeNet.StartPlace.Id);
            Assert.AreEqual(2, madeNet.Places.Count);
            Assert.AreEqual(7, madeNet.Transitions.Count);
        }
Exemple #4
0
        private RelationMatrix MakeEasyNonMatchingIndicesMatrix()
        {
            List <string> activities = new List <string>()
            {
                "c", "b", "a", "d"
            };
            HashSet <string> startActivities = new HashSet <string>()
            {
                "a"
            };
            HashSet <string> endActivities = new HashSet <string>()
            {
                "c"
            };
            RelationMatrix matrix = new RelationMatrix(activities, startActivities, endActivities);

            matrix.Footprint[0, 1] = Relation.Predecession; // d <- c
            matrix.Footprint[0, 3] = Relation.Predecession; // b <- c
            matrix.Footprint[1, 0] = Relation.Succession;   // d -> c
            matrix.Footprint[1, 2] = Relation.Predecession; // a <- d
            matrix.Footprint[2, 1] = Relation.Succession;   // a -> d
            matrix.Footprint[2, 3] = Relation.Succession;   // a -> b
            matrix.Footprint[3, 0] = Relation.Succession;   // b -> c
            matrix.Footprint[3, 2] = Relation.Predecession; // a <- b

            return(matrix);
        }
        private RelationMatrix MakeCycleNetRelationMatrix()
        {
            List <string> activities = new List <string>()
            {
                "a", "b", "c", "d", "e"
            };
            HashSet <string> startActivities = new HashSet <string>()
            {
                "a"
            };
            HashSet <string> endActivities = new HashSet <string>()
            {
                "e"
            };
            RelationMatrix matrix = new RelationMatrix(activities, startActivities, endActivities);

            matrix.Footprint[0, 1] = Relation.Succession;   // a -> b
            matrix.Footprint[1, 0] = Relation.Predecession; // b <- a
            matrix.Footprint[1, 2] = Relation.Succession;   // b -> c
            matrix.Footprint[2, 1] = Relation.Predecession; // c <- b
            matrix.Footprint[2, 3] = Relation.Succession;   // c -> d
            matrix.Footprint[3, 2] = Relation.Predecession; // d <- c
            matrix.Footprint[3, 1] = Relation.Succession;   // d -> b
            matrix.Footprint[1, 3] = Relation.Predecession; // d <- b
            matrix.Footprint[2, 4] = Relation.Succession;   // c -> e
            matrix.Footprint[4, 2] = Relation.Predecession; // c <- e

            return(matrix);
        }
 /// <summary>
 /// Calculates causal footprint comparison of two Relation Matrices.
 /// </summary>
 /// <param name="matrixA">First RelationMatrix to be compared.</param>
 /// <param name="matrixB">Second RelationMatrix to be compared.</param>
 /// <returns>Fitness metric of both matrices.</returns>
 public static double Compare(RelationMatrix matrixA, RelationMatrix matrixB)
 {
     if (IndicesAreMatching(matrixA.ActivityIndices, matrixB.ActivityIndices))
     {
         return(CalculateWhenIndicesMatch(matrixA, matrixB));
     }
     return(Calculate(matrixA, matrixB));
 }
        //Метод получения первичной информации о связях таблиц из БД
        private bool GetDBTablesRelations(RelationMatrix relationMatrix)
        {
            ;
            using (var sConn = new NpgsqlConnection(sConnStr)) {
                //Проверка подключения
                try {
                    sConn.Open();
                }
                catch {
                    return(false);
                }
                //Формируем команду
                var sCommand = new NpgsqlCommand {
                    Connection  = sConn,
                    CommandText = @"
SELECT t1.table_name AS base_table,
       t1.column_name AS base_column,
       t2.table_name AS aim_table,
       t2.column_name AS aim_column
FROM information_schema.key_column_usage AS t1
         JOIN
     information_schema.constraint_column_usage AS t2
     ON t1.constraint_schema = t2.constraint_schema AND t1.constraint_name = t2.constraint_name
         JOIN
     information_schema.table_constraints AS t3
     ON t2.constraint_schema = t3.constraint_schema AND t2.constraint_name = t3.constraint_name
WHERE t3.constraint_type = 'FOREIGN KEY' AND t1.constraint_schema = 'public'
"
                };
                //Запрос и заполнение списка
                using (var reader = sCommand.ExecuteReader()) {
                    while (reader.Read())
                    {
                        var    baseTableName       = (string)reader["base_table"];
                        var    baseColumnName      = (string)reader["base_column"];
                        var    aimTableName        = (string)reader["aim_table"];
                        var    aimColumnName       = (string)reader["aim_column"];
                        string connectionCondition = $"\"{baseTableName}\".\"{baseColumnName}\" = \"{aimTableName}\".\"{aimColumnName}\"";

                        //Создаём двухстороннюю связь
                        relationMatrix[baseTableName][aimTableName] =
                            new RelationMatixElem {
                            ViaTable            = aimTableName,
                            ConnectionCondition = connectionCondition
                        };
                        relationMatrix[aimTableName][baseTableName] =
                            new RelationMatixElem {
                            ViaTable            = baseTableName,
                            ConnectionCondition = connectionCondition
                        };
                    }
                }
            }
            return(true);
        }
Exemple #8
0
        public void CompareDifferentMatricesTest()
        {
            // Arrange
            RelationMatrix matrixA = MakeEasyRelationMatrix();
            RelationMatrix matrixB = MakeHardRelationMatrix();

            // Act
            double fitness = FootprintComparer.Compare(matrixA, matrixB);

            // Assert
            Assert.AreNotEqual(1.0, fitness);
        }
Exemple #9
0
        public void AnalyzeMatricesWithNonMatchingIndicesTest()
        {
            // Arrange
            RelationMatrix matrixA = MakeEasyRelationMatrix();
            RelationMatrix matrixB = MakeEasyNonMatchingIndicesMatrix();

            // Act
            double fitness = FootprintComparer.Compare(matrixA, matrixB);

            // Assert
            Assert.AreEqual(1.0, fitness);
        }
Exemple #10
0
        /// <summary>
        /// Creates a Petri Net from given relation matrix.
        /// </summary>
        /// <param name="matrix">A RelationMatrix used for creating a Petri Net.</param>
        /// <returns>Created PetriNet object.</returns>
        public static PetriNet MakePetriNet(RelationMatrix matrix)
        {
            List <ITransition>          transitions     = GetTransitions(matrix.Activities);
            List <IPlace>               places          = new List <IPlace>();
            HashSet <HashSet <string> > independentSets = IndependentSetUtils.FindIndependentSets(matrix.Footprint, matrix.Activities);
            HashSet <Tuple <HashSet <string>, HashSet <string> > > setsAB = IndependentSetUtils.FindMaximalIndependentSetsAB(independentSets, matrix.Footprint, matrix.ActivityIndices);

            int id = SetupStartPlace(places, matrix.StartActivities, transitions);

            id = SetupPlaces(setsAB, places, transitions, id);
            SetupEndPlace(places, matrix.EndActivities, transitions, id);

            return(new PetriNet(transitions, places, places[0], places[^ 1]));
 /// <summary>
 /// Goes through all fields in Relation matrix and marks predecessions accordingly.
 /// Successions and parallelism needs to be already marked.
 /// </summary>
 /// <param name="matrix">A relation matrix of analyzed Petri Net.</param>
 private static void UpdatePredecessions(ref RelationMatrix matrix)
 {
     for (int from = 0; from < matrix.Activities.Count; from++)
     {
         for (int to = 0; to < matrix.Activities.Count; to++)
         {
             if (matrix.Footprint[from, to] == Relation.Succession)
             {
                 matrix.Footprint[to, from] = Relation.Predecession;
             }
         }
     }
 }
Exemple #12
0
        public void CompareEasyPetriNetWithSameMatrixTest()
        {
            // Arrange
            RelationMatrix matrixA = MakeEasyRelationMatrix();
            IPetriNet      net     = MakeEasyPetriNet();
            RelationMatrix matrixB = PetriNetAnalyzer.MakeRelationMatrix(net);

            // Act
            double fitness = FootprintComparer.Compare(matrixA, matrixB);

            // Assert
            Assert.AreEqual(1.0, fitness);
        }
        public void CompareLogWithAccordingPetriNetTest()
        {
            // Arrange
            ImportedEventLog elog = CSVImport.MakeDataFrame(hardCsv);
            elog.SetActivity("act");
            elog.SetCaseId("id");
            WorkflowLog wlog = new WorkflowLog(elog);
            RelationMatrix matrix = new RelationMatrix(wlog);
            IPetriNet madeNet = Alpha.MakePetriNet(matrix);

            // Act
            double fitness = Computations.ComputeFitness(elog, madeNet);

            // Assert
            Assert.AreEqual(1.0, fitness);
        }
        /// <summary>
        /// Calculates causal footprint comparison when indices of both matrices match.
        /// </summary>
        /// <param name="matrixA">First RelationMatrix to be compared.</param>
        /// <param name="matrixB">Second RelationMatrix to be compared.</param>
        /// <returns>Fitness metric of both matrices.</returns>
        private static double CalculateWhenIndicesMatch(RelationMatrix matrixA, RelationMatrix matrixB)
        {
            int bound = matrixA.Activities.Count;
            int match = 0;
            int size  = bound * bound;

            for (int i = 0; i < bound; i++)
            {
                for (int j = 0; j < bound; j++)
                {
                    if (matrixA.Footprint[i, j] == matrixB.Footprint[i, j])
                    {
                        match++;
                    }
                }
            }
            return(match / size);
        }
Exemple #15
0
        public void MakeRelationMatrixFromActivitiesTest()
        {
            // Arrange
            List <string> activities = new List <string>()
            {
                "wake up", "have coffee", "have tea", "work", "go home", "go sleep", "play witcher"
            };
            HashSet <string> startActivities = new HashSet <string>()
            {
                "wake up"
            };
            HashSet <string> endActivities = new HashSet <string>()
            {
                "go sleep", "play witcher"
            };

            Relation[,] exampleFootprint = new Relation[7, 7];

            // Act
            RelationMatrix matrix = new RelationMatrix(activities, startActivities, endActivities);

            // Assert
            Assert.AreEqual(matrix.Activities.Count, 7);
            for (int i = 0; i < matrix.Activities.Count; i++)
            {
                Assert.AreEqual(activities[i], matrix.Activities[i]);
                Assert.AreEqual(i, matrix.ActivityIndices[matrix.Activities[i]]);
            }
            Assert.AreEqual(1, matrix.StartActivities.Count);
            Assert.IsTrue(matrix.StartActivities.Contains("wake up"));
            Assert.AreEqual(2, matrix.EndActivities.Count);
            Assert.IsTrue(matrix.EndActivities.Contains("go sleep"));
            Assert.IsTrue(matrix.EndActivities.Contains("play witcher"));

            for (int i = 0; i < matrix.Activities.Count; i++)
            {
                for (int j = 0; j < matrix.Activities.Count; j++)
                {
                    Assert.AreEqual(exampleFootprint[i, j], matrix.Footprint[i, j]);
                }
            }
        }
        /// <summary>
        /// Creates a relation matrix accordingly to given Petri Net.
        /// </summary>
        /// <param name="net">Petri Net to be analyzed.</param>
        /// <returns>RelationMatrix of given Petri Net.</returns>
        public static RelationMatrix MakeRelationMatrix(IPetriNet net)
        {
            List <string>    activities      = GetActivities(net.Transitions);
            HashSet <string> startActivities = GetStartActivities(net.Transitions, net.StartPlace);
            HashSet <string> endActivities   = GetEndActivities(net.Transitions, net.EndPlace);
            RelationMatrix   matrix          = new RelationMatrix(activities, startActivities, endActivities);

            foreach (ITransition t in net.GetStartTransitions())
            {
                FindSuccessions(ref matrix, t, net);
            }

            var analysisOverlay = new PetriNetTokenTraverseOverlay(net);

            FindParallelism(ref matrix, analysisOverlay);

            UpdatePredecessions(ref matrix);

            return(matrix);
        }
        public void CompareMildlyTamperedLogWithHardPetriNetTest()
        {
            // Arrange
            ImportedEventLog elog = CSVImport.MakeDataFrame(hardCsv);
            elog.SetActivity("act");
            elog.SetCaseId("id");
            WorkflowLog wlog = new WorkflowLog(elog);
            RelationMatrix matrix = new RelationMatrix(wlog);
            IPetriNet madeNet = Alpha.MakePetriNet(matrix);

            ImportedEventLog tamperedLog = CSVImport.MakeDataFrame(tamperedHardCsv);
            tamperedLog.SetActivity("act");
            tamperedLog.SetCaseId("id");

            // Act
            double fitness = Computations.ComputeFitness(tamperedLog, madeNet);

            // Assert
            Assert.AreEqual(96, (int)(fitness*100));
        }
        //Метод формирования матрицы связей таблиц БД. (параметр)(матрица достижимости)
        public RelationMatrix GetRelationMatrix(List <TableInfo> tables)
        {
            RelationMatrix relationMatrix = new RelationMatrix(tables);

            //Заполним матрицу первоначальными данными. Не смогли - ошибка
            if (!GetDBTablesRelations(relationMatrix))
            {
                return(null);
            }
            //Составляем список имён всех таблиц
            var allTableNames = new List <string>();

            foreach (var table in tables)
            {
                allTableNames.Add(table.TableName);
            }
            //Заполняем матрицу
            foreach (var baseTableName in allTableNames)
            {
                //Получаем список соседей этой таблицы
                var neighborTableNames = relationMatrix.GetNeighborTablesNames(baseTableName);
                //Для каждого соседа ищем достижимые вершины
                foreach (var neighborTableName in neighborTableNames)
                {
                    var reachebleTables = new HashSet <string>(); //множество достижимых из соседней таблицы таблиц
                    reachebleTables.Add(baseTableName);           //базовая таблица достижима - в неё идти не надо
                    relationMatrix.GetConnectedTablesNames(reachebleTables, neighborTableName);
                    reachebleTables.Remove(baseTableName);        //убираем базовую таблицу из множества достижимых - здесь она нам не нужна
                    //Помечаем достижимые из соседа вершины как достижимые из базовой таблицы, делаем в матрице соотв. запись
                    foreach (var reachebleTableName in reachebleTables)
                    {
                        relationMatrix[baseTableName][reachebleTableName] = new RelationMatixElem {
                            ViaTable            = neighborTableName,
                            ConnectionCondition = relationMatrix[baseTableName][neighborTableName].ConnectionCondition
                        }
                    }
                    ;
                }
            }
            return(relationMatrix);
        }
        /// <summary>
        /// Calculates causal footprint comparison when it is unknown if indices of both matrices match or when they don't match.
        /// </summary>
        /// <param name="matrixA">First RelationMatrix to be compared.</param>
        /// <param name="matrixB">Second RelationMatrix to be compared.</param>
        /// <returns>Fitness metric of both matrices.</returns>
        private static double Calculate(RelationMatrix matrixA, RelationMatrix matrixB)
        {
            Dictionary <int, int> indexMapping = new Dictionary <int, int>();

            foreach (KeyValuePair <string, int> logIndex in matrixA.ActivityIndices)
            {
                int modelIndex = matrixB.ActivityIndices[logIndex.Key];
                if (modelIndex != logIndex.Value)
                {
                    indexMapping.Add(logIndex.Value, modelIndex);
                }
            }

            int bound = matrixA.Activities.Count;
            int match = 0;
            int size  = bound * bound;

            for (int i = 0; i < bound; i++)
            {
                for (int j = 0; j < bound; j++)
                {
                    int from = i;
                    int to   = j;
                    if (indexMapping.ContainsKey(i))
                    {
                        from = indexMapping[i];
                    }
                    if (indexMapping.ContainsKey(j))
                    {
                        to = indexMapping[j];
                    }
                    if (matrixA.Footprint[i, j] == matrixB.Footprint[from, to])
                    {
                        match++;
                    }
                }
            }
            return(match / size);
        }
        /// <summary>
        /// Finds all transitions that come directly after the beginningTransition in given Petri Net and updates given Relation DirectDependencyMatrix accordingly.
        /// </summary>
        /// <param name="matrix">A relation matrix of analyzed Petri Net.</param>
        /// <param name="beginningTransition">A beginning transition.</param>
        /// <param name="net">Analyzed Petri Net.</param>
        private static void FindSuccessions(ref RelationMatrix matrix, ITransition beginningTransition, IPetriNet net)
        {
            int                fromIndex       = matrix.ActivityIndices[beginningTransition.Activity];
            List <int>         toIndices       = new List <int>();
            List <ITransition> nextTransitions = new List <ITransition>();

            foreach (ITransition t in net.Transitions)
            {
                foreach (IPlace op in beginningTransition.OutputPlaces)
                {
                    if (t.InputPlaces.Contains(op))
                    {
                        toIndices.Add(matrix.ActivityIndices[t.Activity]);
                        nextTransitions.Add(t);
                    }
                }
            }

            foreach (int toIndex in toIndices)
            {
                matrix.Footprint[fromIndex, toIndex] = Relation.Succession;
            }

            foreach (ITransition t in nextTransitions)
            {
                bool visited = false;
                for (int i = 0; i < matrix.Activities.Count; i++)
                {
                    if (matrix.Footprint[matrix.ActivityIndices[t.Activity], i] == Relation.Succession)
                    {
                        visited = true;
                    }
                }
                if (!visited)
                {
                    FindSuccessions(ref matrix, t, net);
                }
            }
        }
Exemple #21
0
        public void MakeRelationMatrixFromEventLogTest()
        {
            // Arrange
            ImportedEventLog elog = CSVImport.MakeDataFrame(easyCsv);

            elog.SetActivity("act");
            elog.SetCaseId("id");
            WorkflowLog   wlog = new WorkflowLog(elog);
            List <string> exampleActivities = new List <string>()
            {
                "a", "b", "c", "d"
            };

            Relation[,] exampleFootprint = MakeEasyRelationMatrix();

            // Act
            RelationMatrix matrix = new RelationMatrix(wlog);

            // Assert
            Assert.AreEqual(matrix.Activities.Count, 4);
            for (int i = 0; i < matrix.Activities.Count; i++)
            {
                Assert.AreEqual(exampleActivities[i], matrix.Activities[i]);
                Assert.AreEqual(i, matrix.ActivityIndices[matrix.Activities[i]]);
            }
            Assert.AreEqual(1, matrix.StartActivities.Count);
            Assert.IsTrue(matrix.StartActivities.Contains("a"));
            Assert.AreEqual(1, matrix.EndActivities.Count);
            Assert.IsTrue(matrix.EndActivities.Contains("c"));

            for (int i = 0; i < matrix.Activities.Count; i++)
            {
                for (int j = 0; j < matrix.Activities.Count; j++)
                {
                    Assert.AreEqual(exampleFootprint[i, j], matrix.Footprint[i, j]);
                }
            }
        }
 /// <summary>
 /// Finds parallelism in Petri Net overlay and updates given Relation DirectDependencyMatrix accordingly.
 /// </summary>
 /// <param name="matrix">A relation matrix of analyzed Petri Net.</param>
 /// <param name="net">Petri Net overlay.</param>
 private static void FindParallelism(ref RelationMatrix matrix, PetriNetTokenTraverseOverlay net)
 {
     foreach (var fromTransition in net.TransitionsWithFootprints)
     {
         foreach (var toTransition in net.TransitionsWithFootprints)
         {
             if (fromTransition.Id != toTransition.Id)
             {
                 HashSet <string> fromTransitionGlobalIds = new HashSet <string>(
                     TokenManipulationUtils.GetActiveGlobalIds(fromTransition.TokenFootprint));
                 HashSet <string> toTransitionGlobalIds = new HashSet <string>(
                     TokenManipulationUtils.GetActiveGlobalIds(toTransition.TokenFootprint));
                 if (fromTransitionGlobalIds.Overlaps(toTransitionGlobalIds) && !IsFalseParallelism(fromTransition, toTransition))
                 {
                     int fromIndex = matrix.ActivityIndices[fromTransition.Activity];
                     int toIndex   = matrix.ActivityIndices[toTransition.Activity];
                     matrix.Footprint[fromIndex, toIndex] = Relation.Parallelism;
                     matrix.Footprint[toIndex, fromIndex] = Relation.Parallelism;
                 }
             }
         }
     }
 }
        private IPetriNet MakeEasyPetriNet()
        {
            RelationMatrix matrix = MakeEasyRelationMatrix();

            return(Alpha.MakePetriNet(matrix));
        }
        private IPetriNet MakeVeryHardPetriNet()
        {
            RelationMatrix matrix = MakeVeryHardRelationMatrix();

            return(Alpha.MakePetriNet(matrix));
        }