public void CopyNestedTest()
        {
            var dcrGraph = new DcrGraph();

            var activityA = new Activity("A", "somename1") { Included = true };
            var activityB = new Activity("B", "somename2") { Included = true };
            var activityC = new Activity("C", "somename3") { Included = true };
            var activityD = new Activity("D", "somename4") { Included = false };
            var activityE = new Activity("E", "somename5") { Included = true };
            var activityF = new Activity("F", "somename6") { Included = true };

            dcrGraph.AddActivity(activityC.Id, activityC.Name);
            dcrGraph.AddActivity(activityD.Id, activityD.Name);
            dcrGraph.AddActivity(activityE.Id, activityE.Name);
            dcrGraph.AddIncludeExclude(true, activityC.Id, activityD.Id);
            dcrGraph.AddActivity(activityA.Id, activityA.Name);
            dcrGraph.AddActivity(activityB.Id, activityB.Name);
            dcrGraph.AddActivity(activityF.Id, activityF.Name);
            dcrGraph.AddCondition(activityE.Id, activityF.Id); //outgoing relation
            //ingoing relations
            dcrGraph.AddCondition(activityA.Id, activityC.Id);
            dcrGraph.AddCondition(activityA.Id, activityD.Id);
            dcrGraph.AddCondition(activityA.Id, activityE.Id);

            dcrGraph.MakeNestedGraph(new HashSet<Activity>() { activityC, activityD, activityE });

            var copy = dcrGraph.Copy();

            Assert.AreEqual(dcrGraph.ToString(), copy.ToString());
        }
        public void CopyTest()
        {
            DcrGraph dcrGraph = new DcrGraph();

            var activityA = new Activity("A", "somename1") { Included = true, Pending = true };
            var activityB = new Activity("B", "somename2") { Included = true };
            var activityC = new Activity("C", "somename3") { Included = false };

            dcrGraph.AddActivities(activityA, activityB, activityC);

            dcrGraph.AddIncludeExclude(true, activityA.Id, activityB.Id);
            dcrGraph.AddIncludeExclude(true, activityB.Id, activityC.Id);

            var copy = dcrGraph.Copy();

            Assert.AreEqual(dcrGraph.ToString(), copy.ToString());
        }
        private static void FindUniqueStatesInclRunnableActivityCountDepthFirst(DcrGraph inputGraph)
        {
            Counter++;
            var activitiesToRun = inputGraph.GetRunnableActivities();

            var hashed = DcrGraph.HashDcrGraph(inputGraph);
             _seenStatesWithRunnableActivityCount.Add(hashed, activitiesToRun.Select(x => x.Id).ToList().Count);

            foreach (var activity in activitiesToRun)
            {
                // Spawn new work
                var inputGraphCopy = inputGraph.Copy();
                inputGraphCopy.Running = true;
                inputGraphCopy.Execute(inputGraphCopy.GetActivity(activity.Id));

                var stateSeen = _seenStatesWithRunnableActivityCount.ContainsKey(DcrGraph.HashDcrGraph(inputGraphCopy));

                if (!stateSeen)
                {
                    // Register wish to continue
                    FindUniqueStatesInclRunnableActivityCountDepthFirst(inputGraphCopy);
                }
            }
        }
        private static void FindUniqueStatesInclRunnableActivityCount(DcrGraph inputGraph)
        {
            Counter++;
            var activitiesToRun = inputGraph.GetRunnableActivities();
            var iterations = new List<DcrGraph>();

            _seenStates.Add(inputGraph);

            var hashed = DcrGraph.HashDcrGraph(inputGraph);
            if (! _seenStatesWithRunnableActivityCount.ContainsKey(hashed))
            {
                _seenStatesWithRunnableActivityCount.Add(hashed, activitiesToRun.Select(x => x.Id).ToList().Count);
            }

            foreach (var activity in activitiesToRun)
            {
                // Spawn new work
                var inputGraphCopy = inputGraph.Copy();
                inputGraphCopy.Running = true;
                inputGraphCopy.Execute(inputGraphCopy.GetActivity(activity.Id));

                var stateSeen = _seenStates.Any(seenState => seenState.AreInEqualState(inputGraphCopy));

                if (!stateSeen)
                {
                    // Register wish to continue
                    iterations.Add(inputGraphCopy);
                }
            }

            // For each case where we want to go deeper, recurse
            foreach (var unseenState in iterations)
            {
                FindUniqueStatesInclRunnableActivityCount(unseenState);
            }
        }
        //for conditions & Milestones.
        public static DcrGraph PostProcessing(DcrGraph graph)
        {
            var copy = graph.Copy();

            copy = CreateNests(copy);
            
            PostProcessingResultEvent?.Invoke(copy);
            return copy;
        }
        public static DcrGraph CreateNests(DcrGraph graph)
        {
            var copy = graph.Copy();
            List<HashSet<Activity>> combinations = new List<HashSet<Activity>>();

            //for all tuples of the size activites.count -1 size down to the minimumSize. Try if they can be made nested.
            for (int numberToTry = copy.Activities.Count - 1; numberToTry >= MinimumNestedSize; numberToTry--)
            {
                GetSubsets(copy.Activities.ToList(),numberToTry,0,new HashSet<Activity>(),combinations);
            }

            foreach (var activities in combinations)
            {
                if (CanMakeNested(copy, activities))
                {
                    copy.MakeNestedGraph(activities);
                    //if we actually make a nested graph. Make it and then call the create nest-method again.
                    copy = CreateNests(copy);
                }
            }

            return copy;
        }
        public DcrGraph RemoveRedundancy(DcrGraph inputGraph, BackgroundWorker worker = null)
        {
            _worker = worker;
            #if DEBUG
            Console.WriteLine("Started redundancy removal:");
            #endif

            //TODO: use an algorithm to check if the graph is connected and if not then recursively remove redundancy on the subgraphs.
            //temporarily remove flower activities.
            var copy = inputGraph.Copy();

            var removedActivities =
                copy.GetActivities().Where(x => (x.Included && !copy.ActivityHasRelations(x))).ToList();

            foreach (var a in removedActivities)
            {
                copy.RemoveActivity(a.Id);
            }

            var byteDcrGraph = new ByteDcrGraph(copy);

            _uniqueTraceFinder = new UniqueTraceFinder(byteDcrGraph);

            _originalInputDcrGraph = copy.Copy();
            OutputDcrGraph = copy;

            // Remove relations and see if the unique traces acquired are the same as the original. If so, the relation is clearly redundant and is removed immediately
            // All the following calls potentially alter the OutputDcrGraph

            RemoveRedundantRelations(RelationType.Response);

            RemoveRedundantRelations(RelationType.Condition);

            RemoveRedundantRelations(RelationType.InclusionExclusion);

            RemoveRedundantRelations(RelationType.Milestone);

            foreach (var activity in OutputDcrGraph.GetActivities())
            {
                var graphCopy = new ByteDcrGraph(byteDcrGraph);

                graphCopy.RemoveActivity(activity.Id);

                ReportProgress?.Invoke("Removing Activity " + activity.Id);

                // Compare unique traces - if equal activity is redundant
                if (_uniqueTraceFinder.CompareTraces(graphCopy))
                {
                    // The relation is redundant, replace  copy with current copy (with the relation removed)
                    OutputDcrGraph.RemoveActivity(activity.Id);
                }

            }

            foreach (var a in removedActivities)
            {
                OutputDcrGraph.AddActivity(a.Id, a.Name);
                OutputDcrGraph.SetIncluded(true, a.Id);
                OutputDcrGraph.SetPending(a.Pending, a.Id);
            }
            var nested = OutputDcrGraph.ExportToXml();

            return OutputDcrGraph;
        }
        public void TestCopyMethod()
        {
            var dcrGraph = new DcrGraph();
            var activityA = new Activity("A", "somename1");
            var activityB = new Activity("B", "somename2");
            var activityC = new Activity("C", "somename3");
            dcrGraph.Activities.Add(activityA);
            dcrGraph.Activities.Add(activityB);
            dcrGraph.Activities.Add(activityC);
            dcrGraph.IncludeExcludes.Add(activityA, new Dictionary<Activity, bool> { { activityB, true }, { activityC, false } });
            dcrGraph.Conditions.Add(activityA, new HashSet<Activity> { activityB, activityC });

            Console.WriteLine(dcrGraph);

            Console.WriteLine("--------------------------------------------------------------------------------");

            var copy = dcrGraph.Copy();
            Console.WriteLine(copy);
            Console.ReadKey();
        }
        public void SomeTestForFindingTracesBeforeAfterStuff()
        {
            var dcr = new DcrGraph();
            dcr.AddActivities(new Activity("A", "A"), new Activity("B", "B"), new Activity("C", "C"));
            dcr.AddCondition("A", "B");
            dcr.AddCondition("A", "C");
            dcr.AddCondition("B", "C");
            dcr.SetIncluded(true, "A");
            dcr.SetIncluded(true, "B");
            dcr.SetIncluded(true, "C");
            dcr.SetPending(true, "C");

            var traceFinder = new UniqueTraceFinder(new ByteDcrGraph(dcr));

            dcr = dcr.Copy();
            dcr.RemoveCondition("A", "B");
            traceFinder = new UniqueTraceFinder(new ByteDcrGraph(dcr));
        }
 private void UpdateGraphWithPostProcessingResult(DcrGraph postProcessedGraph)
 {
     Dispatcher.Invoke(() =>
     {
         GraphToDisplay = postProcessedGraph.Copy();
     });
 }