Exemplo n.º 1
0
        public static void showAutomaton(DeterministicFiniteAutomaton G, string name = "Automaton")
        {
            string path = $"{name}.html";

            var source = new StringBuilder();

            source.AppendLine("<!DOCTYPE HTML>");
            source.AppendLine("<HTML>");
            source.AppendLine("\t<HEAD>");
            source.AppendFormat("\t\t<TITLE>{0}</TITLE>", G.Name);
            source.AppendLine("\t</HEAD>");
            source.AppendLine("\t<BODY>");
            source.AppendLine("\t\t<script type=\"text/vnd.graphviz\" id=\"cluster\">");
            source.AppendLine(G.ToDotCode);
            source.AppendLine("\t\t</script>"); //
            //source.AppendLine(@"<script src=""Drawing/viz.js""></script>");
            source.AppendLine(@"<script src=""https://github.com/mdaines/viz.js/releases/download/v1.8.0/viz.js""></script>");
            source.AppendLine(@"        
            <script>
               function inspect(s) {
            return ""<pre>"" + s.replace(/</g, ""&lt;"").replace(/>/g, ""&gt;"").replace(/\""/g, ""&quot;"") + ""</pre>""
               }
               function src(id) {
            return document.getElementById(id).innerHTML;
               }
               function example(id, format, engine) {
            var result;
            try {
               result = Viz(src(id), format, engine);
               if (format === ""svg"")
            return result;
               else
            return inspect(result);
            } catch(e) {
               return inspect(e.toString());
            }
               }
               document.body.innerHTML += example(""cluster"", ""svg"");
        </script>");
            source.AppendLine("\t</BODY>");
            source.AppendLine("</HTML>");

            using (var file = new StreamWriter(path))
            {
                file.WriteLine(source.ToString());
            }

            //Process.Start(path);
            Process.Start(@"cmd.exe ", $@"/c {path}");
            Thread.Sleep(1000);
        }
Exemplo n.º 2
0
        //gera arquivo de desenho do autômato
        public static void drawLatexFigure(DeterministicFiniteAutomaton G, string fileName, bool openAfterFinish = true)
        {
            string fontSize = "normalsize";
            Dictionary <string, DrawingState> statesList = prepare(G);
            Vector max, min;

            getMaxAndMin(statesList, out max, out min);

            foreach (var item in statesList)
            {
                var y = item.Value.position.Y - min.Y + Constants.AREA_LIMIT_OFFSET;
                var x = item.Value.position.X - min.X + Constants.AREA_LIMIT_OFFSET;
                item.Value.position = new Vector(x, y);
            }

            if (!fileName.EndsWith(".txt") && !fileName.EndsWith(".tex"))
            {
                fileName += ".txt";
            }

            StreamWriter writer = new StreamWriter(fileName);

            //cria cabeçalho
            FigureStream.WriteLatexHeader(writer, max.X + Constants.AREA_LIMIT_OFFSET,
                                          max.Y - max.Y + 2 * Constants.AREA_LIMIT_OFFSET);

            //inverte as cordenas y para desenho no latex
            foreach (var item in statesList)
            {
                item.Value.position = new Vector(item.Value.position.X, -item.Value.position.Y);
                FigureStream.drawLatexState(writer, item.Value, Constants.STATE_RADIUS, fontSize);
            }

            FigureStream.drawFigureLatex(writer, statesList, fontSize);

            //termina arquivo
            FigureStream.WriteLatexEnd(writer);
            writer.Close();

            if (openAfterFinish)
            {
                System.Diagnostics.Process.Start(fileName);
            }
        }
Exemplo n.º 3
0
        //gera arquivo de desenho do autômato
        public static void drawSVG(DeterministicFiniteAutomaton G, string fileName, bool openAfterFinish = true)
        {
            Dictionary <string, DrawingState> statesList = prepare(G);
            Vector max, min;

            getMaxAndMin(statesList, out max, out min);

            foreach (var item in statesList)
            {
                var y = item.Value.position.Y - min.Y + Constants.AREA_LIMIT_OFFSET;
                var x = item.Value.position.X - min.X + Constants.AREA_LIMIT_OFFSET;
                item.Value.position = new Vector(x, y);
            }

            if (!fileName.EndsWith(".svg"))
            {
                fileName += ".svg";
            }

            StreamWriter writer = new StreamWriter(fileName);

            //cria cabeçalho
            FigureStream.WriteSVGHeader(writer, max.X + Constants.AREA_LIMIT_OFFSET,
                                        max.Y - min.Y + 2 * Constants.AREA_LIMIT_OFFSET);

            foreach (var item in statesList)
            {
                FigureStream.drawSVGState(writer, item.Value, Constants.STATE_RADIUS);
            }

            FigureStream.drawFigureSVG(writer, statesList);

            //termina arquivo
            FigureStream.WriteSVGEnd(writer);
            writer.Close();

            if (openAfterFinish)
            {
                System.Diagnostics.Process.Start(fileName);
            }
        }
Exemplo n.º 4
0
        //Simula a dinamica de força do sistema
        /// <summary>
        /// Prepares the specified g.
        /// </summary>
        /// <param name="G">The g.</param>
        /// <returns>Dictionary&lt;System.String, DrawingState&gt;.</returns>
        private static Dictionary <string, DrawingState> prepare(DeterministicFiniteAutomaton G)
        {
            //CRIANDO MÉTODO QUE SERA UTILIZADO PARA O DESENVOLVIMENTO DA BIBLIOTECA

            var drawingStatesList = new Dictionary <string, DrawingState>();           // lista de estados com cordenadas

            //Cria uma lista de estados com parametros de posição para serem desenhados
            foreach (var item in G.States)
            {
                var state = new DrawingState(item.ToString(), item.Marking)
                {
                    initialState = item.Equals(G.InitialState)
                };
                drawingStatesList.Add(item.ToString(), state);
            }

            // aloca os estados dentro de um circulo de raio e centro que serão determinados

            var radius = Constants.SPRING_LENGTH * drawingStatesList.Count;
            var center = new Vector(radius + Constants.AREA_LIMIT_OFFSET, radius + Constants.AREA_LIMIT_OFFSET);

            initialConfiguration(drawingStatesList, radius, center);

            // Atraves da lista de transiçoes associa para cada estado quais sao os estados de origem e qual era o anterior;

            foreach (var item in G.Transitions)
            {
                if (drawingStatesList.TryGetValue(item.Origin.ToString(), out var state))
                {
                    var transitionName = item.Trigger + ((item.IsControllableTransition) ? "" : "'");
                    state.addDestination(drawingStatesList[item.Destination.ToString()], transitionName);
                }
                if (drawingStatesList.TryGetValue(item.Destination.ToString(), out state))
                {
                    state.addOrigin(drawingStatesList[item.Origin.ToString()]);
                }
            }


            var force        = new Vector();
            var biggestForce = new Vector();

            for (int j = 0; j < Constants.MAX_ITERATIONS; ++j)
            {
                force.X = 0;
                force.Y = 0;

                foreach (var item in drawingStatesList)
                {
                    var attractionForce = item.Value.attractionForce(Constants.SPRING_CONSTANT, Constants.SPRING_LENGTH);
                    var repulsionForce  = item.Value.repulsionForce(Constants.CONSTANT_OF_REPULSION, drawingStatesList);
                    force = attractionForce + repulsionForce;

                    if (force.Length > biggestForce.Length)
                    {
                        biggestForce = force;
                    }

                    // desloca estado para uma posição melhor
                    if (item.Value.initialState)
                    {
                        continue;
                    }
                    var position = item.Value.position + Constants.DELTA * force;
                    position.X          = Max(position.X, Constants.AREA_LIMIT_OFFSET);
                    position.X          = Min(position.X, Constants.AREA_LIMIT_OFFSET + 2 * radius);
                    position.Y          = Max(position.Y, Constants.AREA_LIMIT_OFFSET);
                    position.Y          = Min(position.Y, Constants.AREA_LIMIT_OFFSET + 2 * radius);
                    item.Value.position = position;
                }
                if (biggestForce.Length <= Constants.STOP_CRITERION.Length)
                {
                    break;
                }
            }
            return(drawingStatesList);
        }
Exemplo n.º 5
0
        public FJSSP(string file)
        {
            try
            {
                string[] lines_str = System.IO.File.ReadAllLines(file);

                var matriz = new List <List <int> >();

                for (int i = 0; i < lines_str.Count(); i++)
                {
                    matriz.Add(new List <int>());
                    var line = lines_str[i].Split(' ');
                    for (int j = 0; j < line.Count(); j++)
                    {
                        if (line[j] != "")
                        {
                            int.TryParse(line[j], out int aux);
                            matriz[i].Add(aux);
                        }
                    }
                }

                var jobs = matriz[0][0]; var job_names = new string[jobs]; for (int i = 1; i <= jobs; i++)
                {
                    job_names[i - 1] = $"j{i}";
                }
                var maquinas = matriz[0][1]; var maq_names = new string[maquinas]; for (int i = 1; i <= maquinas; i++)
                {
                    maq_names[i - 1] = $"m{i}";
                }
                var op = 0;

                for (int i = 1; i < matriz.Count(); i++)
                {
                    op += matriz[i][0];
                }
                Depth = op * 2;
                var states_maq = new Dictionary <int, State>();
                states_maq[0] = new State($"s{0}", Marking.Marked); states_maq[1] = new State($"s{1}", Marking.Unmarked); states_maq[2] = new State($"s{2}", Marking.Unmarked);

                List <Transition>         transitions_jobs = new List <Transition>();
                List <List <Transition> > transitions_maq  = new List <List <Transition> >(); for (int i = 0; i < maquinas; i++)
                {
                    transitions_maq.Add(new List <Transition>());
                }
                Dictionary <string, DFA> DFA_jobs = new Dictionary <string, DFA>();
                Dictionary <string, DFA> DFA_maq  = new Dictionary <string, DFA>();
                List <int> next = new List <int>();

                List <int> atual    = new List <int> {
                };
                List <int> anterior = atual.ToList();

                for (int i = 1; i < jobs + 1; i++) // cada job
                {
                    atual.Clear();
                    anterior.Clear();
                    int idx = 1;
                    for (int j = 1; j < matriz[i][0] + 1; j++)   // cada operação
                    {
                        for (int k = 0; k < matriz[i][idx]; k++) // cada máquina
                        {
                            if (j != matriz[i][0])               // não é a última operação
                            {
                                if (anterior.Count == 0)
                                {
                                    e.Add(new Event($"a{i}{j}{matriz[i][idx + (2 * k) + 1]}{0}", Controllability.Controllable));                                                          // cria evento a[job,op,maq,orig]
                                    transitions_jobs.Add(new Transition(new State($"s{2 * (j - 1)}.{0}", Marking.Unmarked), e.Last(), new State($"s{2 * j - 1}.{k}", Marking.Unmarked))); // inclui evento a no job
                                    transitions_maq[matriz[i][idx + (2 * k) + 1] - 1].Add(new Transition(states_maq[0], e.Last(), states_maq[1]));                                        // inclui evento a na maq de 0 para 1
                                    time.Add(e.Last(), matriz[i][idx + (2 * k) + 2]);
                                    e.Add(new Event($"b{i}{j}{matriz[i][idx + (2 * k) + 1]}{0}", Controllability.Uncontrollable));                                                        // cria evento b[job,op,maq,orig]
                                    transitions_jobs.Add(new Transition(new State($"s{2 * j - 1}.{k}", Marking.Unmarked), e.Last(), new State($"s{2 * j}.{0}", Marking.Unmarked)));       // inclui evento b no job
                                    transitions_maq[matriz[i][idx + (2 * k) + 1] - 1].Add(new Transition(states_maq[1], e.Last(), states_maq[2]));                                        // inclui evento b na maq de 1 para 2
                                    atual.Add(matriz[i][idx + (2 * k) + 1]);                                                                                                              // inclui máquina atual
                                }

                                else if (anterior.Count == 1)
                                {
                                    if (matriz[i][idx + (2 * k) + 1] == anterior[0])                                                                                                          // se máquina atual é igual a anterior
                                    {
                                        e.Add(new Event($"a{i}{j}{matriz[i][idx + (2 * k) + 1]}{anterior[0]}", Controllability.Controllable));                                                // cria evento a[job,op,maq,orig]
                                        transitions_jobs.Add(new Transition(new State($"s{2 * (j - 1)}.{0}", Marking.Unmarked), e.Last(), new State($"s{2 * j - 1}.{k}", Marking.Unmarked))); // inclui evento a no job
                                        transitions_maq[matriz[i][idx + (2 * k) + 1] - 1].Add(new Transition(states_maq[2], e.Last(), states_maq[1]));                                        // inclui evento a na maq de 2 para 1
                                        time.Add(e.Last(), matriz[i][idx + (2 * k) + 2]);
                                        e.Add(new Event($"b{i}{j}{matriz[i][idx + (2 * k) + 1]}{anterior[0]}", Controllability.Uncontrollable));                                              // cria evento b[job,op,maq,orig]
                                        transitions_jobs.Add(new Transition(new State($"s{2 * j - 1}.{k}", Marking.Unmarked), e.Last(), new State($"s{2 * j}.{0}", Marking.Unmarked)));       // inclui evento b no job
                                        transitions_maq[matriz[i][idx + (2 * k) + 1] - 1].Add(new Transition(states_maq[1], e.Last(), states_maq[2]));                                        // inclui evento b na maq de 1 para 2
                                        atual.Add(matriz[i][idx + (2 * k) + 1]);                                                                                                              // inclui máquina atual
                                    }
                                    else
                                    {
                                        e.Add(new Event($"a{i}{j}{matriz[i][idx + (2 * k) + 1]}{anterior[0]}", Controllability.Controllable));                                                // cria evento a[job,op,maq,orig]
                                        transitions_jobs.Add(new Transition(new State($"s{2 * (j - 1)}.{0}", Marking.Unmarked), e.Last(), new State($"s{2 * j - 1}.{k}", Marking.Unmarked))); // inclui evento a no job
                                        transitions_maq[matriz[i][idx + (2 * k) + 1] - 1].Add(new Transition(states_maq[0], e.Last(), states_maq[1]));                                        // inclui evento a na maq de 0 para 1
                                        transitions_maq[anterior[0] - 1].Add(new Transition(states_maq[2], e.Last(), states_maq[0]));                                                         // inclui evento a na maq anterior de 2 para 0
                                        time.Add(e.Last(), matriz[i][idx + (2 * k) + 2]);
                                        e.Add(new Event($"b{i}{j}{matriz[i][idx + (2 * k) + 1]}{anterior[0]}", Controllability.Uncontrollable));                                              // cria evento b[job,op,maq,orig]
                                        transitions_jobs.Add(new Transition(new State($"s{2 * j - 1}.{k}", Marking.Unmarked), e.Last(), new State($"s{2 * j}.{0}", Marking.Unmarked)));       // inclui evento b no job
                                        transitions_maq[matriz[i][idx + (2 * k) + 1] - 1].Add(new Transition(states_maq[1], e.Last(), states_maq[2]));                                        // inclui evento b na maq de 1 para 2
                                        atual.Add(matriz[i][idx + (2 * k) + 1]);                                                                                                              // inclui máquina atual
                                    }
                                }

                                else
                                {
                                    for (int m = 0; m < anterior.Count; m++)                                                                                                                      // para cada máquina que processa a operação anterior
                                    {
                                        if (matriz[i][idx + (2 * k) + 1] == anterior[m])                                                                                                          // se máquina atual é igual a anterior
                                        {
                                            e.Add(new Event($"a{i}{j}{matriz[i][idx + (2 * k) + 1]}{anterior[m]}", Controllability.Controllable));                                                // cria evento a[job,op,maq,orig]
                                            transitions_jobs.Add(new Transition(new State($"s{2 * (j - 1)}.{0}", Marking.Unmarked), e.Last(), new State($"s{2 * j - 1}.{k}", Marking.Unmarked))); // inclui evento a no job
                                            transitions_maq[matriz[i][idx + (2 * k) + 1] - 1].Add(new Transition(states_maq[2], e.Last(), states_maq[1]));                                        // inclui evento a na maq de 2 para 1
                                            time.Add(e.Last(), matriz[i][idx + (2 * k) + 2]);
                                            e.Add(new Event($"b{i}{j}{matriz[i][idx + (2 * k) + 1]}{anterior[m]}", Controllability.Uncontrollable));                                              // cria evento b[job,op,maq,orig]
                                            transitions_jobs.Add(new Transition(new State($"s{2 * j - 1}.{k}", Marking.Unmarked), e.Last(), new State($"s{2 * j}.{0}", Marking.Unmarked)));       // inclui evento b no job
                                            transitions_maq[matriz[i][idx + (2 * k) + 1] - 1].Add(new Transition(states_maq[1], e.Last(), states_maq[2]));                                        // inclui evento b na maq de 1 para 2
                                            atual.Add(matriz[i][idx + (2 * k) + 1]);                                                                                                              // inclui máquina atual
                                        }
                                        else
                                        {
                                            e.Add(new Event($"a{i}{j}{matriz[i][idx + (2 * k) + 1]}{anterior[m]}", Controllability.Controllable));                                                // cria evento a[job,op,maq,orig]
                                            transitions_jobs.Add(new Transition(new State($"s{2 * (j - 1)}.{0}", Marking.Unmarked), e.Last(), new State($"s{2 * j - 1}.{k}", Marking.Unmarked))); // inclui evento a no job
                                            transitions_maq[matriz[i][idx + (2 * k) + 1] - 1].Add(new Transition(states_maq[0], e.Last(), states_maq[1]));                                        // inclui evento a na maq de 0 para 1
                                            transitions_maq[anterior[m] - 1].Add(new Transition(states_maq[2], e.Last(), states_maq[0]));                                                         // inclui evento a na maq anterior de 2 para 0
                                            time.Add(e.Last(), matriz[i][idx + (2 * k) + 2]);
                                            e.Add(new Event($"b{i}{j}{matriz[i][idx + (2 * k) + 1]}{anterior[m]}", Controllability.Uncontrollable));                                              // cria evento b[job,op,maq,orig]
                                            transitions_jobs.Add(new Transition(new State($"s{2 * j - 1}.{k}", Marking.Unmarked), e.Last(), new State($"s{2 * j}.{0}", Marking.Unmarked)));       // inclui evento b no job
                                            transitions_maq[matriz[i][idx + (2 * k) + 1] - 1].Add(new Transition(states_maq[1], e.Last(), states_maq[2]));                                        // inclui evento b na maq de 1 para 2
                                            atual.Add(matriz[i][idx + (2 * k) + 1]);                                                                                                              // inclui máquina atual
                                        }
                                    }
                                }
                            }
                            else
                            {
                                if (anterior.Count == 1)
                                {
                                    if (matriz[i][idx + (2 * k) + 1] == anterior[0])                                                                                                                                  // se máquina atual é igual a anterior
                                    {
                                        e.Add(new Event($"a{i}{j}{matriz[i][idx + (2 * k) + 1]}{anterior[0]}", Controllability.Controllable));                                                                        // cria evento a[job,op,maq,orig]
                                        transitions_jobs.Add(new Transition(new State($"s{2 * (j - 1)}.{0}", Marking.Unmarked), e.Last(), new State($"s{2 * j - 1}.{k}", Marking.Unmarked)));                         // inclui evento a no job
                                        transitions_maq[matriz[i][idx + (2 * k) + 1] - 1].Add(new Transition(states_maq[2], e.Last(), states_maq[1]));                                                                // inclui evento a na maq de 2 para 1
                                        time.Add(e.Last(), matriz[i][idx + (2 * k) + 2]);
                                        e.Add(new Event($"b{i}{j}{matriz[i][idx + (2 * k) + 1]}{anterior[0]}", Controllability.Uncontrollable));                                                                      // cria evento b[job,op,maq,orig]
                                        transitions_jobs.Add(new Transition(new State($"s{2 * j - 1}.{k}", Marking.Unmarked), e.Last(), new State($"s{2 * j}.{0}", Marking.Marked)));                                 // inclui evento b no job
                                        transitions_jobs.Add(new Transition(new State($"s{2 * j}.{0}", Marking.Marked), new Event("e", Controllability.Uncontrollable), new State($"s{2 * j}.{0}", Marking.Marked))); // inclui evento e no job
                                        transitions_maq[matriz[i][idx + (2 * k) + 1] - 1].Add(new Transition(states_maq[1], e.Last(), states_maq[0]));                                                                // inclui evento b na maq de 1 para 0
                                        atual.Add(matriz[i][idx + (2 * k) + 1]);                                                                                                                                      // inclui máquina atual
                                    }
                                    else
                                    {
                                        e.Add(new Event($"a{i}{j}{matriz[i][idx + (2 * k) + 1]}{anterior[0]}", Controllability.Controllable));                                                                        // cria evento a[job,op,maq,orig]
                                        transitions_jobs.Add(new Transition(new State($"s{2 * (j - 1)}.{0}", Marking.Unmarked), e.Last(), new State($"s{2 * j - 1}.{k}", Marking.Unmarked)));                         // inclui evento a no job
                                        transitions_maq[matriz[i][idx + (2 * k) + 1] - 1].Add(new Transition(states_maq[0], e.Last(), states_maq[1]));                                                                // inclui evento a na maq de 0 para 1
                                        transitions_maq[anterior[0] - 1].Add(new Transition(states_maq[2], e.Last(), states_maq[0]));                                                                                 // inclui evento a na maq anterior de 2 para 0
                                        time.Add(e.Last(), matriz[i][idx + (2 * k) + 2]);
                                        e.Add(new Event($"b{i}{j}{matriz[i][idx + (2 * k) + 1]}{anterior[0]}", Controllability.Uncontrollable));                                                                      // cria evento b[job,op,maq,orig]
                                        transitions_jobs.Add(new Transition(new State($"s{2 * j - 1}.{k}", Marking.Unmarked), e.Last(), new State($"s{2 * j}.{0}", Marking.Marked)));                                 // inclui evento b no job
                                        transitions_jobs.Add(new Transition(new State($"s{2 * j}.{0}", Marking.Marked), new Event("e", Controllability.Uncontrollable), new State($"s{2 * j}.{0}", Marking.Marked))); // inclui evento e no job
                                        transitions_maq[matriz[i][idx + (2 * k) + 1] - 1].Add(new Transition(states_maq[1], e.Last(), states_maq[0]));                                                                // inclui evento b na maq de 1 para 0
                                        atual.Add(matriz[i][idx + (2 * k) + 1]);                                                                                                                                      // inclui máquina atual
                                    }
                                }

                                else
                                {
                                    for (int m = 0; m < anterior.Count; m++)                                                                                                                                              // para cada máquina que processa a operação anterior
                                    {
                                        if (matriz[i][idx + (2 * k) + 1] == anterior[m])                                                                                                                                  // se máquina atual é igual a anterior
                                        {
                                            e.Add(new Event($"a{i}{j}{matriz[i][idx + (2 * k) + 1]}{anterior[m]}", Controllability.Controllable));                                                                        // cria evento a[job,op,maq,orig]
                                            transitions_jobs.Add(new Transition(new State($"s{2 * (j - 1)}.{0}", Marking.Unmarked), e.Last(), new State($"s{2 * j - 1}.{k}", Marking.Unmarked)));                         // inclui evento a no job
                                            transitions_maq[matriz[i][idx + (2 * k) + 1] - 1].Add(new Transition(states_maq[2], e.Last(), states_maq[1]));                                                                // inclui evento a na maq de 2 para 1
                                            time.Add(e.Last(), matriz[i][idx + (2 * k) + 2]);
                                            e.Add(new Event($"b{i}{j}{matriz[i][idx + (2 * k) + 1]}{anterior[m]}", Controllability.Uncontrollable));                                                                      // cria evento b[job,op,maq,orig]
                                            transitions_jobs.Add(new Transition(new State($"s{2 * j - 1}.{k}", Marking.Unmarked), e.Last(), new State($"s{2 * j}.{0}", Marking.Marked)));                                 // inclui evento b no job
                                            transitions_jobs.Add(new Transition(new State($"s{2 * j}.{0}", Marking.Marked), new Event("e", Controllability.Uncontrollable), new State($"s{2 * j}.{0}", Marking.Marked))); // inclui evento e no job
                                            transitions_maq[matriz[i][idx + (2 * k) + 1] - 1].Add(new Transition(states_maq[1], e.Last(), states_maq[0]));                                                                // inclui evento b na maq de 1 para 0
                                            atual.Add(matriz[i][idx + (2 * k) + 1]);                                                                                                                                      // inclui máquina atual
                                        }
                                        else
                                        {
                                            e.Add(new Event($"a{i}{j}{matriz[i][idx + (2 * k) + 1]}{anterior[m]}", Controllability.Controllable));                                                                        // cria evento a[job,op,maq,orig]
                                            transitions_jobs.Add(new Transition(new State($"s{2 * (j - 1)}.{0}", Marking.Unmarked), e.Last(), new State($"s{2 * j - 1}.{k}", Marking.Unmarked)));                         // inclui evento a no job
                                            transitions_maq[matriz[i][idx + (2 * k) + 1] - 1].Add(new Transition(states_maq[0], e.Last(), states_maq[1]));                                                                // inclui evento a na maq de 0 para 1
                                            transitions_maq[anterior[0] - 1].Add(new Transition(states_maq[2], e.Last(), states_maq[0]));                                                                                 // inclui evento a na maq anterior de 2 para 0
                                            time.Add(e.Last(), matriz[i][idx + (2 * k) + 2]);
                                            e.Add(new Event($"b{i}{j}{matriz[i][idx + (2 * k) + 1]}{anterior[m]}", Controllability.Uncontrollable));                                                                      // cria evento b[job,op,maq,orig]
                                            transitions_jobs.Add(new Transition(new State($"s{2 * j - 1}.{k}", Marking.Unmarked), e.Last(), new State($"s{2 * j}.{0}", Marking.Marked)));                                 // inclui evento b no job
                                            transitions_jobs.Add(new Transition(new State($"s{2 * j}.{0}", Marking.Marked), new Event("e", Controllability.Uncontrollable), new State($"s{2 * j}.{0}", Marking.Marked))); // inclui evento e no job
                                            transitions_maq[matriz[i][idx + (2 * k) + 1] - 1].Add(new Transition(states_maq[1], e.Last(), states_maq[0]));                                                                // inclui evento b na maq de 1 para 0
                                            atual.Add(matriz[i][idx + (2 * k) + 1]);                                                                                                                                      // inclui máquina atual
                                        }
                                    }
                                }
                            }
                        }

                        idx      = idx + matriz[i][idx] * 2 + 1;
                        atual    = atual.Distinct().ToList();
                        anterior = atual.ToList();
                        atual.Clear();
                    }

                    DFA_jobs.Add(job_names[i - 1], new DFA(transitions_jobs, new State($"s{0}.{0}", Marking.Unmarked), job_names[i - 1]));
                    transitions_jobs.Clear();
                }

                e.Add(new Event("e", Controllability.Uncontrollable));

                for (int i = 0; i < transitions_maq.Count(); i++)
                {
                    transitions_maq[i].Add(new Transition(states_maq[0], new Event("e", Controllability.Uncontrollable), states_maq[0]));
                    DFA_maq.Add(maq_names[i], new DFA(transitions_maq[i], states_maq[0], maq_names[i]));
                }

                Supervisor = DFA.MonolithicSupervisor(DFA_jobs.Values, DFA_maq.Values, true);

                e = e.Distinct().ToList();
            }
            catch (Exception erro)
            {
                Console.WriteLine("Erro: " + erro.Message);
            }
        }
Exemplo n.º 6
0
        /// <summary>
        /// Observers the property verify.
        /// </summary>
        /// <param name="G">The g.</param>
        /// <param name="relevantArray">The relevant array.</param>
        /// <param name="Vg">The vg.</param>
        /// <param name="returnOnDead">if set to <c>true</c> [return on dead].</param>
        /// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
        public static bool ObserverPropertyVerify(this DeterministicFiniteAutomaton G, AbstractEvent[] relevantArray, out NondeterministicFiniteAutomaton Vg, bool returnOnDead = true)
        {
            var  tau      = new Event("Tau", Controllability.Controllable);
            var  dead     = new State("DEAD", Marking.Marked);
            bool findDead = false;
            var  relevant = new HashSet <AbstractEvent>(relevantArray)
            {
                tau
            };
            var irrelevant     = new HashSet <AbstractEvent>(G.Events.Except(relevant));
            var transitionsAux = G.Transitions.Union(G.MarkedStates.Select(q => (Transition)(q, tau, q))).ToList();

            var M = StronglyConnectedComponentsAutomaton((transitionsAux, G.InitialState), irrelevant);

            var transitions = M.transitions.GroupBy(t => t.Origin).ToDictionary(g => g.Key, g => g.ToArray());

            var Q  = new HashSet <(AbstractState, AbstractState)>();
            var Qt = new HashSet <(AbstractState, AbstractState)>()
            {
                (M.initial, M.initial)
            };
            var vgTransitions = new HashSet <Transition>();

            //Vg = (VgTransitions, G.InitialState);

            while (Qt.Except(Q).Any())
            {
                var Qtemp = new HashSet <(AbstractState, AbstractState)>();
                foreach (var q in Qt.Except(Q))
                {
                    Q.Add(q);

                    var(q1, q2) = q;

                    var origin = q1 == q2
                        ? q1
                        : (new[] { q1, q2 }).OrderBy(qq => qq.ToString())
                                 .Aggregate((a, b) => a.MergeWith(b));

                    var Enq1 = new HashSet <AbstractEvent>(transitions.ContainsKey(q1)
                        ? transitions[q1].Select(t => t.Trigger)
                        : new AbstractEvent[0]).Distinct();
                    var Enq2 = new HashSet <AbstractEvent>(transitions.ContainsKey(q2)
                        ? transitions[q2].Select(t => t.Trigger)
                        : new AbstractEvent[0]).Distinct();

                    foreach (var sigma in Enq1.Union(Enq2))
                    {
                        if (relevant.Contains(sigma))
                        {
                            if (Enq1.Contains(sigma) && Enq2.Contains(sigma))
                            {
                                var d1s = transitions[q1].Where(t => t.Trigger == sigma).Select(t => t.Destination);
                                var d2s = transitions[q2].Where(t => t.Trigger == sigma).Select(t => t.Destination);



                                foreach (var d2 in d2s)
                                {
                                    foreach (var d1 in d1s)
                                    {
                                        var destination = d1 == d2
                                            ? d1
                                            : (new[] { d1, d2 }).OrderBy(qq => qq.ToString())
                                                          .Aggregate((a, b) => a.MergeWith(b));
                                        Qtemp.Add((d1, d2));
                                        vgTransitions.Add((origin, sigma, destination));
                                    }
                                }
                            }
                            else if ((Enq1.Contains(sigma) && !Enq2.Intersect(irrelevant).Any()) ||
                                     (Enq2.Contains(sigma) && !Enq1.Intersect(irrelevant).Any()))
                            {
                                Qtemp.Add((dead, dead));
                                vgTransitions.Add((origin, sigma, dead));
                            }
                        }
                        else
                        {
                            if (Enq1.Contains(sigma))
                            {
                                var d1s = transitions[q1].Where(t => t.Trigger == sigma).Select(t => t.Destination);
                                foreach (var d1 in d1s)
                                {
                                    var destination = d1 == q2
                                        ? d1
                                        : (new[] { d1, q2 }).OrderBy(qq => qq.ToString())
                                                      .Aggregate((a, b) => a.MergeWith(b));

                                    Qtemp.Add((d1, q2));
                                    vgTransitions.Add((origin, sigma, destination));
                                }
                            }

                            if (Enq2.Contains(sigma))
                            {
                                var d2s = transitions[q2].Where(t => t.Trigger == sigma).Select(t => t.Destination);
                                foreach (var d2 in d2s)
                                {
                                    var destination = q1 == d2
                                        ? q1
                                        : (new[] { q1, d2 }).OrderBy(qq => qq.ToString())
                                                      .Aggregate((a, b) => a.MergeWith(b));

                                    Qtemp.Add((q1, d2));
                                    vgTransitions.Add((origin, sigma, destination));
                                }
                            }
                        }
                    }
                }

                Qt.UnionWith(Qtemp);
                if (Qtemp.Contains((dead, dead)))
                {
                    if (returnOnDead)
                    {
                        Vg = new NondeterministicFiniteAutomaton(vgTransitions, G.InitialState, $"OBS({G})");
                        return(false);
                    }
                    else
                    {
                        findDead = true;
                    }
                }
            }

            Vg = new NondeterministicFiniteAutomaton(vgTransitions, G.InitialState, $"OBS({G})");
            return(!findDead);
        }
Exemplo n.º 7
0
        /// <summary>
        /// Observers the property search.
        /// </summary>
        /// <param name="G">The g.</param>
        /// <param name="relevantArray">The relevant array.</param>
        /// <returns>NondeterministicFiniteAutomaton.</returns>
        public static NondeterministicFiniteAutomaton ObserverPropertySearch(this DeterministicFiniteAutomaton G, AbstractEvent[] relevantArray)
        {
            var tau  = new Event("Tau", Controllability.Controllable);
            var dead = new State("DEAD", Marking.Marked);

            var relevant = new HashSet <AbstractEvent>(relevantArray)
            {
                tau
            };
            var irrelevant     = new HashSet <AbstractEvent>(G.Events.Except(relevant));
            var transitionsAux = G.Transitions.Select(t => (Transition)(t.Origin.Flatten, t.Trigger, t.Destination.Flatten))
                                 .Union(G.MarkedStates.Select(q => (Transition)(q, tau, q))).ToList();


            int renameIdx = 1;

            while (true)
            {
                var M       = StronglyConnectedComponentsAutomaton((transitionsAux, G.InitialState), irrelevant);
                var hasDead = FindDead(M, relevant, irrelevant, dead, out HashSet <((AbstractState q1, AbstractState q2) o, AbstractEvent t, (AbstractState q1, AbstractState q2) d)> VgTransitions);

                if (!hasDead)
                {
                    return(new NondeterministicFiniteAutomaton(VgTransitions.Where(t =>
                                                                                   string.CompareOrdinal(t.o.q1.ToString(), t.o.q2.ToString()) >= 0 &&
                                                                                   string.CompareOrdinal(t.d.q1.ToString(), t.d.q2.ToString()) >= 0).Select(
                                                                   t =>
                    {
                        var origin = t.o.q1 == t.o.q2 ? t.o.q1 : t.o.q1.MergeWith(t.o.q2);
                        var destination = t.d.q1 == t.d.q2 ? t.d.q1 : t.d.q1.MergeWith(t.d.q2);
                        return new Transition(origin, t.t, destination);
                    }), M.initial, $"OBS({G})"));
                }

                var initial  = (dead, dead);
                var frontier = new List <((AbstractState q1, AbstractState q2) o, AbstractEvent t, (AbstractState q1, AbstractState q2) d)>();

                frontier.AddRange(VgTransitions.Where(t => t.d == initial));

                while (frontier.All(t => t.o.q1 != t.o.q2))
                {
                    var newFrontier = new List <((AbstractState q1, AbstractState q2) o, AbstractEvent t, (AbstractState q1, AbstractState q2) d)>();
                    foreach (var t2 in frontier)
                    {
                        newFrontier.AddRange(VgTransitions.Where(t => t.d == t2.o && t.d != t.o));
                    }

                    frontier = newFrontier;
                }

                var(o, _, _) = frontier.First(t => t.o.q1 == t.o.q2);

                foreach (var q in o.q1.S)
                {
                    var trans = transitionsAux.Where(t => t.Origin == q && !relevant.Contains(t.Trigger));
                    if (!trans.Any())
                    {
                        continue;
                    }
                    var removeTrans   = trans.First();
                    var originalEvent = removeTrans.Trigger;
                    var renamedEvent  = new Event($"{originalEvent}'_{renameIdx++}", originalEvent.Controllability);
                    relevant.Add(renamedEvent);

                    transitionsAux.Remove(removeTrans);
                    transitionsAux.Add(new Transition(removeTrans.Origin, renamedEvent, removeTrans.Destination));
                    break;
                }
            }
        }