Пример #1
0
        public static Sequence<Sequence<CompoundTerm>> GenerateTestSequences(FSM fa)
        {
            //Eliminate dead states from the fa
            Set<Term> deadStates = GetDeadStates(fa);
            Set<Term> aliveStates = fa.States.Difference(deadStates);
            Set<Triple<Term, CompoundTerm, Term>> aliveTransitions =
                fa.Transitions.Select(delegate(Triple<Term, CompoundTerm, Term> trans)
                {
                    return aliveStates.Contains(trans.First) &&
                           aliveStates.Contains(trans.Third);
                });
            if (aliveTransitions.IsEmpty) //test suite cannot be generated
                return Sequence<Sequence<CompoundTerm>>.EmptySequence;

            //Build a graph from the alive transitions
            Term[] states = new Term[aliveStates.Count];
            Dictionary<Term, int> stateToVertexMap = new Dictionary<Term, int>();
            states[0] = fa.InitialState;
            stateToVertexMap[fa.InitialState] = 0;
            int i = 1;
            foreach (Term state in aliveStates.Remove(fa.InitialState))
            {
                states[i] = state;
                stateToVertexMap[state] = i++;
            }

            //create edges that must be traversed
            GraphTraversals.Edge[] mustEdges = new GraphTraversals.Edge[aliveTransitions.Count];
            Triple<Term, CompoundTerm, Term>[] mustTransitions = new Triple<Term, CompoundTerm, Term>[aliveTransitions.Count];
            i = 0;
            foreach (Triple<Term, CompoundTerm, Term> trans in aliveTransitions)
            {
                GraphTraversals.Edge edge = new GraphTraversals.Edge(stateToVertexMap[trans.First],
                    stateToVertexMap[trans.Third], i);
                mustEdges[i] = edge;
                mustTransitions[i++] = trans;
            }

            //add an optional edge with label -1 from every accepting state
            //to the initial state, this corresponds to a reset action
            GraphTraversals.Edge[] optionalEdges =
                new GraphTraversals.Edge[fa.AcceptingStates.Count];
            i = 0;
            foreach (Term accState in fa.AcceptingStates)
            {
                int accVertex = stateToVertexMap[accState];
                optionalEdges[i++] = new GraphTraversals.Edge(accVertex, 0, -1); //-1 = reset
            }

            //at this point it is known that g is strongly connected and has no dead states
            //so a postman tour exists, compute a postman tour
            GraphTraversals.Graph g =
                new GraphTraversals.Graph(0, mustEdges, optionalEdges,
                                          GraphTraversals.WeakClosureEnum.DoNotClose);
            List<GraphTraversals.Edge> postmanTour =
                new List<GraphTraversals.Edge>(g.GetRuralChinesePostmanTour());

            #region normalize the tour so that it ends in an accepting state and has a reset at the end as a "watchdog"
            //if the last edge has not label -1, i.e. the edge leading back
            //to the initial state is not a reset edge from an accepting state
            //and the last state is not an accepting state
            //then extend the path to an accepting state, from the beginning of the path
            //notice that there must be at least one accepting state, so such an extesion
            //is indeed possible
            GraphTraversals.Edge lastEdge = postmanTour[postmanTour.Count - 1];
            if (lastEdge.label >= 0) //if the last edge is a reset, we are done
            {
                //the last edge leads back to the initial state, because this is a tour
                if (fa.AcceptingStates.Contains(fa.InitialState))
                    postmanTour.Add(new GraphTraversals.Edge(0, 0, -1)); //add a watchdog
                else
                {
                    //create an extesion to the tour from the initial state to the first accepting state
                    List<GraphTraversals.Edge> extension = new List<GraphTraversals.Edge>();
                    foreach (GraphTraversals.Edge edge in postmanTour)
                    {
                        extension.Add(edge);
                        if (fa.AcceptingStates.Contains(states[edge.target]))
                        {
                            //the end state of the edge is accepting, so we are done
                            extension.Add(new GraphTraversals.Edge(0, 0, -1)); //add a watchdog
                            break;
                        }

                    }
                    postmanTour.AddRange(extension);
                }
            }
            #endregion

            #region break up the tour into sequences of transition ids separated by the reset edge
            List<List<int>> paths = new List<List<int>>();
            List<int> path = new List<int>();
            for (int k = 0; k < postmanTour.Count; k++)
            {
                //presense of the watchdog at the end of the tour is assumed here
                GraphTraversals.Edge edge = postmanTour[k];
                if (edge.label < 0) //encountered reset, end of path
                {
                    paths.Add(path);
                    path = new List<int>();
                }
                else
                {
                    path.Add(edge.label);
                }
            }
            #endregion

            #region map the paths into action sequences
            Sequence<Sequence<CompoundTerm>> res = Sequence<Sequence<CompoundTerm>>.EmptySequence;
            foreach (List<int> path1 in paths)
            {
                Sequence<CompoundTerm> transSeq = Sequence<CompoundTerm>.EmptySequence;
                foreach (int transId in path1)
                    transSeq = transSeq.AddLast(mustTransitions[transId].Second);
                res = res.AddLast(transSeq);
            }
            #endregion

            return res;
        }
Пример #2
0
        public static Sequence <Sequence <CompoundTerm> > GenerateTestSequences(FSM fa)
        {
            //Eliminate dead states from the fa
            Set <Term> deadStates  = GetDeadStates(fa);
            Set <Term> aliveStates = fa.States.Difference(deadStates);
            Set <Triple <Term, CompoundTerm, Term> > aliveTransitions =
                fa.Transitions.Select(delegate(Triple <Term, CompoundTerm, Term> trans)
            {
                return(aliveStates.Contains(trans.First) &&
                       aliveStates.Contains(trans.Third));
            });

            if (aliveTransitions.IsEmpty) //test suite cannot be generated
            {
                return(Sequence <Sequence <CompoundTerm> > .EmptySequence);
            }

            //Build a graph from the alive transitions
            Term[] states = new Term[aliveStates.Count];
            Dictionary <Term, int> stateToVertexMap = new Dictionary <Term, int>();

            states[0] = fa.InitialState;
            stateToVertexMap[fa.InitialState] = 0;
            int i = 1;

            foreach (Term state in aliveStates.Remove(fa.InitialState))
            {
                states[i] = state;
                stateToVertexMap[state] = i++;
            }

            //create edges that must be traversed
            GraphTraversals.Edge[] mustEdges = new GraphTraversals.Edge[aliveTransitions.Count];
            Triple <Term, CompoundTerm, Term>[] mustTransitions = new Triple <Term, CompoundTerm, Term> [aliveTransitions.Count];
            i = 0;
            foreach (Triple <Term, CompoundTerm, Term> trans in aliveTransitions)
            {
                GraphTraversals.Edge edge = new GraphTraversals.Edge(stateToVertexMap[trans.First],
                                                                     stateToVertexMap[trans.Third], i);
                mustEdges[i]         = edge;
                mustTransitions[i++] = trans;
            }

            //add an optional edge with label -1 from every accepting state
            //to the initial state, this corresponds to a reset action
            GraphTraversals.Edge[] optionalEdges =
                new GraphTraversals.Edge[fa.AcceptingStates.Count];
            i = 0;
            foreach (Term accState in fa.AcceptingStates)
            {
                int accVertex = stateToVertexMap[accState];
                optionalEdges[i++] = new GraphTraversals.Edge(accVertex, 0, -1); //-1 = reset
            }

            //at this point it is known that g is strongly connected and has no dead states
            //so a postman tour exists, compute a postman tour
            GraphTraversals.Graph g =
                new GraphTraversals.Graph(0, mustEdges, optionalEdges,
                                          GraphTraversals.WeakClosureEnum.DoNotClose);
            List <GraphTraversals.Edge> postmanTour =
                new List <GraphTraversals.Edge>(g.GetRuralChinesePostmanTour());

            #region normalize the tour so that it ends in an accepting state and has a reset at the end as a "watchdog"
            //if the last edge has not label -1, i.e. the edge leading back
            //to the initial state is not a reset edge from an accepting state
            //and the last state is not an accepting state
            //then extend the path to an accepting state, from the beginning of the path
            //notice that there must be at least one accepting state, so such an extesion
            //is indeed possible
            GraphTraversals.Edge lastEdge = postmanTour[postmanTour.Count - 1];
            if (lastEdge.label >= 0) //if the last edge is a reset, we are done
            {
                //the last edge leads back to the initial state, because this is a tour
                if (fa.AcceptingStates.Contains(fa.InitialState))
                {
                    postmanTour.Add(new GraphTraversals.Edge(0, 0, -1)); //add a watchdog
                }
                else
                {
                    //create an extesion to the tour from the initial state to the first accepting state
                    List <GraphTraversals.Edge> extension = new List <GraphTraversals.Edge>();
                    foreach (GraphTraversals.Edge edge in postmanTour)
                    {
                        extension.Add(edge);
                        if (fa.AcceptingStates.Contains(states[edge.target]))
                        {
                            //the end state of the edge is accepting, so we are done
                            extension.Add(new GraphTraversals.Edge(0, 0, -1)); //add a watchdog
                            break;
                        }
                    }
                    postmanTour.AddRange(extension);
                }
            }
            #endregion

            #region break up the tour into sequences of transition ids separated by the reset edge
            List <List <int> > paths = new List <List <int> >();
            List <int>         path  = new List <int>();
            for (int k = 0; k < postmanTour.Count; k++)
            {
                //presense of the watchdog at the end of the tour is assumed here
                GraphTraversals.Edge edge = postmanTour[k];
                if (edge.label < 0) //encountered reset, end of path
                {
                    paths.Add(path);
                    path = new List <int>();
                }
                else
                {
                    path.Add(edge.label);
                }
            }
            #endregion

            #region map the paths into action sequences
            Sequence <Sequence <CompoundTerm> > res = Sequence <Sequence <CompoundTerm> > .EmptySequence;
            foreach (List <int> path1 in paths)
            {
                Sequence <CompoundTerm> transSeq = Sequence <CompoundTerm> .EmptySequence;
                foreach (int transId in path1)
                {
                    transSeq = transSeq.AddLast(mustTransitions[transId].Second);
                }
                res = res.AddLast(transSeq);
            }
            #endregion

            return(res);
        }