Beispiel #1
0
        //chooses a random word with at least n
        private static string RegularGetRandomWord(StringDFA dfa, string currentState, int nRest)
        {
            if (currentState.Equals("-1"))
            {
                return(null);
            }

            if (dfa.F.Contains(currentState) && nRest <= 0)
            {
                return("");
            }

            if (nRest < lowestNRest)
            {
                return(shortestAcceptingWord(dfa, currentState));
            }

            string[] alphArr = new string[dfa.alphabet.Count];
            dfa.alphabet.CopyTo(alphArr, 0);
            HashSet <string> letters = new HashSet <string>(alphArr);

            while (letters.Any())
            {
                int    i      = randInt(0, letters.Count);
                string letter = letters.ToArray()[i];
                letters.Remove(letter);
                string state        = dfa.getStateFromState(letter, currentState);
                string returnedWord = RegularGetRandomWord(dfa, state, nRest - 1);
                if (returnedWord != null)
                {
                    return(letter + returnedWord);
                }
            }
            return(null);
        }
Beispiel #2
0
        // returns start and end index (both inclusive) of mid word
        private static TwoTuple <int, int> detectLoopFromState(StringDFA dfa, string currentState, string word, int n)
        {
            List <string> statesVisited = new List <string>();

            if (!dfa.Accepts(word))
            {
                throw new PumpingLemmaException("Automaton does not accept this word!");
            }

            statesVisited.Add(currentState);
            int currentLetter = 0;

            while (currentLetter <= n && currentLetter < word.Length)
            {
                string newState = dfa.delta[new TwoTuple <string, string>(currentState, word.ElementAt(currentLetter) + "")];
                if (statesVisited.Contains(newState))
                {
                    int index = statesVisited.IndexOf(newState);
                    return(new TwoTuple <int, int>(index, currentLetter));
                }
                else
                {
                    currentLetter++;
                    currentState = newState;
                    statesVisited.Add(currentState);
                }
            }
            return(null);
        }
Beispiel #3
0
        private static bool RegularCheckSplit(StringDFA dfa, string start, string mid, string end)
        {
            string fullWord = pumpMid(start, mid, end, 1);
            HashSet <Tuple <string, string, string> > equivalentSplits = new HashSet <Tuple <string, string, string> >();

            equivalentSplits.Add(new Tuple <string, string, string>(start, mid, end));


            for (int k = 1; k <= mid.Length; k++)
            {
                string newEnd   = String.Copy(end);
                string newStart = String.Copy(start);

                while (newEnd.Length >= k)
                {
                    string pre = mid.Length > k?mid.Substring(k) : "";

                    if (pre + newEnd.Substring(0, k) == mid)
                    {
                        newEnd   = newEnd.Substring(k);
                        newStart = newStart + mid.Substring(0, k);
                        equivalentSplits.Add(new Tuple <string, string, string>(newStart, mid, newEnd));
                    }
                    else
                    {
                        break;
                    }
                }

                newEnd   = String.Copy(end);
                newStart = String.Copy(start);
                while (newStart.Length >= k)
                {
                    string post = mid.Length > k?mid.Substring(0, k) : "";

                    if (newStart.Substring(newStart.Length - k) + post == mid)
                    {
                        newEnd   = mid.Substring(mid.Length - k) + newEnd;
                        newStart = newStart.Substring(0, newStart.Length - k);
                        equivalentSplits.Add(new Tuple <string, string, string>(newStart, mid, newEnd));
                    }
                    else
                    {
                        break;
                    }
                }
            }

            foreach (var split in equivalentSplits)
            {
                //check whether mid is a loop
                string stateAfterStart = dfa.getStateFromState(split.Item1, dfa.q_0);
                if (stateAfterStart.Equals(dfa.getStateFromState(split.Item2, stateAfterStart)))
                {
                    return(true);
                }
            }
            return(false);
        }
Beispiel #4
0
        public static Tuple <string, string, string> RegularGetSplit(StringDFA dfa, string word, int n)
        {
            TwoTuple <int, int> midIndex = detectLoopFromState(dfa, dfa.q_0, word, n);

            if (midIndex != null)
            {
                string start = word.Substring(0, midIndex.first);
                string mid   = word.Substring(midIndex.first, midIndex.second - midIndex.first + 1);
                string end   = word.Substring(midIndex.second + 1);
                return(Tuple.Create(start, mid, end));
            }
            return(null);
        }
        public DFA <string, HashSet <State <Set <State <string> > > > > ToDFA()
        {
            //check if every variable appears only once
            varsSeen = new HashSet <VariableType>();
            if (!checkVariableOnce(symbolic_string))
            {
                throw new PumpingLemmaException("Each variable must only appear once!");
            }

            NFA <string, string> nfa = null;
            var epsilonTransitions   = new HashSet <TwoTuple <State <string>, State <string> > >();

            ArithmeticLanguage unaryLanguage = this;
            var comparisons = unaryLanguage.getReducedUnaryConstraints();

            currentId = 0;

            //only epsilon
            if (symbolic_string.isEpsilon())
            {
                var startState = new State <string>(0, "0");
                var finalState = new State <string>(1, "1");
                var states     = new HashSet <State <string> >();
                states.Add(startState);
                states.Add(finalState);
                var Q_0 = new HashSet <State <string> >();
                Q_0.Add(startState);
                var F = new HashSet <State <string> >();
                F.Add(startState);
                var delta = new Dictionary <TwoTuple <State <string>, string>, HashSet <State <string> > >();
                foreach (var letter in alphabet)
                {
                    delta.Add(new TwoTuple <State <string>, string>(startState, letter), new HashSet <State <string> >(new State <string>[] { finalState }));
                }
                nfa = new NFA <string, string>(states, new HashSet <string>(alphabet), delta, Q_0, F);
            }
            else
            {
                var tuple = epsNFA(symbolic_string, new HashSet <string>(alphabet), comparisons);
                nfa = tuple.Item1;
                epsilonTransitions = tuple.Item2;
            }

            NFA <string, string> nfaCollected = StringDFA.collectEpsilonTransitions(nfa.Q, new HashSet <string>(alphabet), nfa.delta, nfa.Q_0, nfa.F, epsilonTransitions);

            var dfa     = nfaCollected.NFAtoDFA();
            var dfa_min = dfa.MinimizeHopcroft();

            return(dfa_min);
        }
Beispiel #6
0
        public static string RegularGetWord(StringDFA dfa, int n)
        {
            if (dfa.states.Count <= n)
            {
                //choose random word
                return(RegularGetRandomWord(dfa, dfa.q_0, n));
            }

            //choose word that doesn't contain loop
            string word = RegularGetUnpumpableWord(dfa, dfa.q_0, new HashSet <string>(new string[] { dfa.q_0 }), n);

            if (word == null)
            {
                return(RegularGetRandomWord(dfa, dfa.q_0, n));
            }
            return(word);
        }
Beispiel #7
0
        /*
         * ----------------------------------------------------------------------------------------------------
         *                                       Decision Making
         * ----------------------------------------------------------------------------------------------------
         */

        public static string RegularCheckWord(StringDFA dfa, int n, string word)
        {
            if (word.Length < n)
            {
                return("<false>Word is too short.</false>");
            }

            foreach (char c in word)
            {
                if (!dfa.alphabet.Contains(c + ""))
                {
                    return("<false>Word contains illegal letters.</false>");
                }
            }

            if (dfa.Accepts(word))
            {
                return("<true></true>");
            }

            return("<false>Word is not in the language.</false>");
        }
Beispiel #8
0
        public static int RegularGetI(StringDFA dfa, string start, string mid, string end)
        {
            if (!dfa.Accepts(start + end))
            {
                return(0);
            }
            if (RegularCheckSplit(dfa, start, mid, end))
            {
                return(1); //AI admits defeat
            }
            int i = 2;

            while (dfa.Accepts(pumpMid(start, mid, end, i)))
            {
                i++;
                //for debuugging purposes:
                if (i > 99)
                {
                    return(1);
                }
            }
            return(i);
        }
Beispiel #9
0
 public static bool RegularCheckI(StringDFA dfa, string start, string mid, string end, int i)
 {
     return(dfa.Accepts(pumpMid(start, mid, end, i)));
 }
Beispiel #10
0
        private static string RegularGetUnpumpableWord(StringDFA dfa, string currentState, HashSet <string> statesUsed, int nRest)
        {
            if (currentState.Equals("-1"))
            {
                return(null);
            }
            if (dfa.F.Contains(currentState) && nRest <= 0)
            {
                return("");
            }

            if (dfa.states.Count == statesUsed.Count)
            {
                return(null);
            }

            string[] alphArr = new string[dfa.alphabet.Count];
            dfa.alphabet.CopyTo(alphArr, 0);
            HashSet <string> letters = new HashSet <string>(alphArr);

            while (letters.Any())
            {
                int    i      = randInt(0, letters.Count);
                string letter = letters.ToArray()[i];
                letters.Remove(letter);

                string state = dfa.getStateFromState(letter, currentState);
                if (nRest > 0)
                {
                    if (!statesUsed.Contains(state))
                    {
                        bool contin = true;
                        foreach (string l in alphArr)
                        {
                            if (statesUsed.Contains(dfa.getStateFromState(l, state)))
                            {
                                contin = false;
                                break;
                            }
                        }
                        if (contin)
                        {
                            HashSet <string> newStatesUsed = new HashSet <string>(statesUsed);
                            newStatesUsed.Add(state);
                            string returnedWord = RegularGetUnpumpableWord(dfa, state, newStatesUsed, nRest - 1);
                            if (returnedWord != null)
                            {
                                return(letter + returnedWord);
                            }
                        }
                    }
                }
                else
                {
                    string returnedWord = RegularGetUnpumpableWord(dfa, state, statesUsed, nRest - 1);
                    if (returnedWord != null)
                    {
                        return(letter + returnedWord);
                    }
                }
            }
            return(null);
        }
Beispiel #11
0
        public static int RegularGetN(StringDFA dfa)
        {
            var newDfa = dfa.ToDFA();

            return(newDfa.Q.Count);
        }
Beispiel #12
0
        private static string shortestAcceptingWord(StringDFA dfa, string state)
        {
            Dictionary <string, int>    stateDistance    = new Dictionary <string, int>();
            Dictionary <string, string> statePredecessor = new Dictionary <string, string>();
            HashSet <string>            allStates        = new HashSet <string>();

            foreach (string s in dfa.states)
            {
                stateDistance.Add(s, Int32.MaxValue);
                statePredecessor.Add(s, null);
                allStates.Add(s);
            }
            stateDistance[state] = 0;
            while (allStates.Any())
            {
                HashSet <KeyValuePair <string, int> > minStates = new HashSet <KeyValuePair <string, int> >();
                var ordered = stateDistance.OrderBy(x => x.Value);
                int i       = 1;
                minStates.Add(ordered.First());
                int minVal = ordered.First().Value;
                while (i < ordered.Count() && minVal == ordered.ElementAt(i).Value)
                {
                    minStates.Add(ordered.ElementAt(i));
                    i++;
                }
                i = randInt(0, minStates.Count());
                var nextState = minStates.ToArray()[i].Key;
                allStates.Remove(nextState);

                HashSet <string> neighbours = new HashSet <string>();
                foreach (var letter in dfa.alphabet)
                {
                    string value = null;
                    if (dfa.delta.TryGetValue(new TwoTuple <string, string>(nextState, letter), out value))
                    {
                        neighbours.Add(value);
                    }
                }
                foreach (string neighbour in neighbours)
                {
                    if (allStates.Contains(neighbour))
                    {
                        int alt = stateDistance[nextState] + 1;
                        if (alt < stateDistance[neighbour])
                        {
                            stateDistance[neighbour]    = alt;
                            statePredecessor[neighbour] = nextState;
                        }
                    }
                }
            }

            HashSet <string> shortestWords = new HashSet <string>();

            foreach (var acceptingState in dfa.F)
            {
                StringBuilder sb        = new StringBuilder();
                string        lastState = acceptingState;
                while (statePredecessor[lastState] != null)
                {
                    string letter = dfa.delta.Where(x =>
                                                    x.Key.first == statePredecessor[lastState] &&
                                                    x.Value == lastState).First().Key.second;
                    sb.Insert(0, letter);
                    lastState = statePredecessor[lastState];
                }
                shortestWords.Add(sb.ToString());
            }

            HashSet <string> minWords = new HashSet <string>();
            var orderedWords          = shortestWords.OrderBy(x => x.Length);
            int j = 1;

            minWords.Add(orderedWords.First());
            int minL = orderedWords.First().Length;

            while (j < orderedWords.Count() && minL == orderedWords.ElementAt(j).Length)
            {
                minWords.Add(orderedWords.ElementAt(j));
                j++;
            }
            j = randInt(0, minWords.Count());
            return(minWords.ToArray()[j]);
        }
Beispiel #13
0
        public StringDFA(XElement automatonXML, bool deterministic)
        {
            AutomatonXML aXML;
            var          xmlSerializer = new XmlSerializer(typeof(AutomatonXML));
            var          doc           = new XDocument();

            doc.Add(automatonXML);
            using (var reader = doc.CreateReader())
            {
                aXML = (AutomatonXML)xmlSerializer.Deserialize(reader);
            }

            if (deterministic)
            {
                this.q_0 = aXML.initState[0].sid;
                this.F   = new HashSet <string>();
                foreach (var state in aXML.acceptingStates)
                {
                    this.F.Add(state.sid);
                }

                this.delta = new Dictionary <TwoTuple <string, string>, string>();
                foreach (var transition in aXML.transitions)
                {
                    delta.Add(new TwoTuple <string, string>(transition.from + "", transition.read), transition.to + "");
                }

                this.states = new HashSet <string>();
                foreach (var state in aXML.states)
                {
                    this.states.Add(state.sid);
                }

                this.alphabet = new HashSet <string>();
                foreach (string letter in aXML.alphabet)
                {
                    alphabet.Add(letter);
                }
            }

            else
            {
                //NFA
                HashSet <State <string> > states = new HashSet <State <string> >();
                foreach (var state in aXML.states)
                {
                    if (Int32.TryParse(state.sid, out int parsed))
                    {
                        states.Add(new State <string>(parsed, state.sid));
                    }
                    else
                    {
                        states.Add(new State <string>(0, state.sid));
                    }
                }
                HashSet <string> alphabet = new HashSet <string>();
                foreach (var letter in aXML.alphabet)
                {
                    alphabet.Add(letter);
                }
                HashSet <TwoTuple <State <string>, State <string> > > epsilonTransitions         = new HashSet <TwoTuple <State <string>, State <string> > >();
                Dictionary <TwoTuple <State <string>, string>, HashSet <State <string> > > delta = new Dictionary <TwoTuple <State <string>, string>, HashSet <State <string> > >();
                foreach (var transition in aXML.transitions)
                {
                    if (transition.read.Equals("epsilon"))
                    {
                        epsilonTransitions.Add(new TwoTuple <State <string>, State <string> >(new State <string>(transition.from + ""), new State <string>(transition.to + "")));
                    }
                    else
                    {
                        TwoTuple <State <string>, string> twoTuple = new TwoTuple <State <string>, string>(new State <string>(transition.from + ""), transition.read);
                        HashSet <State <string> >         set;
                        if (delta.TryGetValue(twoTuple, out set))
                        {
                            set.Add(new State <string>(transition.to + ""));
                        }
                        else
                        {
                            set = new HashSet <State <string> >();
                            set.Add(new State <string>(transition.to + ""));
                            delta.Add(new TwoTuple <State <string>, string>(new State <string>(transition.from + ""), transition.read), set);
                        }
                    }
                }
                HashSet <State <string> > Q_0 = new HashSet <State <string> >();
                foreach (var state in aXML.initState)
                {
                    Q_0.Add(new State <string>(state.sid));
                }
                HashSet <State <string> > F = new HashSet <State <string> >();
                foreach (var state in aXML.acceptingStates)
                {
                    F.Add(new State <string>(state.sid));
                }

                var nfa = collectEpsilonTransitions(states, alphabet, delta, Q_0, F, epsilonTransitions);

                var dfa     = nfa.NFAtoDFA();
                var dfa_min = dfa.MinimizeHopcroft();
                var strDFA  = new StringDFA(dfa_min);

                //rename error set
                foreach (var state in strDFA.states)
                {
                    if (!strDFA.F.Contains(state))
                    {
                        bool errorStateFound = true;
                        foreach (var letter in strDFA.alphabet)
                        {
                            if (!strDFA.delta[new TwoTuple <string, string>(state, letter)].Equals(state))
                            {
                                errorStateFound = false;
                                break;
                            }
                        }
                        if (errorStateFound)
                        {
                            strDFA.states.Remove(state);
                            strDFA.states.Add("-1");
                            if (strDFA.q_0.Equals(state))
                            {
                                strDFA.q_0 = "-1";
                            }

                            HashSet <KeyValuePair <TwoTuple <string, string>, string> > entriesToChange = new HashSet <KeyValuePair <TwoTuple <string, string>, string> >();
                            foreach (var entry in strDFA.delta)
                            {
                                if (entry.Value.Equals(state))
                                {
                                    entriesToChange.Add(entry);
                                }
                            }
                            foreach (var entry in entriesToChange)
                            {
                                strDFA.delta[entry.Key] = "-1";
                            }

                            foreach (var letter in strDFA.alphabet)
                            {
                                strDFA.delta.Remove(new TwoTuple <string, string>(state, letter));
                                strDFA.delta.Add(new TwoTuple <string, string>("-1", letter), "-1");
                            }
                            break;
                        }
                    }
                }


                this.alphabet = strDFA.alphabet;
                this.delta    = strDFA.delta;
                this.F        = strDFA.F;
                this.q_0      = strDFA.q_0;
                this.states   = strDFA.states;
            }
        }