예제 #1
0
 /// <summary>
 /// Add to list of values corresponding to chain key
 /// If list does not exist create it
 /// </summary>
 /// <param name="key"></param>
 /// <param name="value"></param>
 public void AddToChain(ChainKey key, string value)
 {
     if (!_chains.ContainsKey(key))
     {
         _chains.Add(key, new List <string>());
     }
     _chains[key].Add(value);
 }
예제 #2
0
 /// <summary>
 /// Add to list of values corresponding to chain key
 /// If list does not exist create it
 /// </summary>
 /// <param name="key"></param>
 /// <param name="value"></param>
 public void AddToChain(ChainKey key, string value)
 {
     if(!_chains.ContainsKey(key))
     {
         _chains.Add(key, new List<string>()) ;
     }
     _chains[key].Add(value) ;
 }
예제 #3
0
 /// <summary>
 /// Get copy of List of values corresponding to passed in key
 /// </summary>
 /// <param name="key"></param>
 /// <returns>copy of values corresponding to passed in key</returns>
 public List<string> GetValues(ChainKey key)
 {
     List<string> retVals ;
     if(!_chains.TryGetValue(key, out retVals))
     {
         throw new Exceptions.InvalidKey("Invalid key") ;
     }
     return retVals;
 }
예제 #4
0
        /// <summary>
        /// Get copy of List of values corresponding to passed in key
        /// </summary>
        /// <param name="key"></param>
        /// <returns>copy of values corresponding to passed in key</returns>
        public List <string> GetValues(ChainKey key)
        {
            List <string> retVals;

            if (!_chains.TryGetValue(key, out retVals))
            {
                throw new Exceptions.InvalidKey("Invalid key");
            }
            return(retVals);
        }
예제 #5
0
 public void T_GetValues()
 {
     ChainMap cm = InitSimpleChainMapp() ;
     ChainKey keyNull = new ChainKey(new string[]{null, "word1"}) ;
     ChainKey key1 = new ChainKey(new string[]{"word1", "word2"}) ;
     ChainKey key2 = new ChainKey(new string[]{"word2", "word3"}) ;
     ChainKey keyIncorrect = new ChainKey(new string[]{"word2", "word1"}) ;
     CollectionAssert.AreEquivalent(cm.GetValues(keyNull), new List<string>{"valnull"}) ;
     CollectionAssert.AreEquivalent(cm.GetValues(key1), new List<string>{"val1", "val3"}) ;
     CollectionAssert.AreEquivalent(cm.GetValues(key2), new List<string>{"val2"}) ;
     Assert.Throws(typeof(Exceptions.InvalidKey),
                   delegate { cm.GetValues(keyIncorrect);});
 }
예제 #6
0
        /// <summary>
        /// Get next word.  If the next natural word does not obey given predicate, throw exception
        /// If we reach the end of the list get random key matching end condition passed in Reset
        /// </summary>
        /// <param name="condition"> Predicate next word must obey </param>
        /// <returns></returns>
        public string GetNextWord(Predicate <string> condition)
        {
            //If word generator has never been reset, reset with default values
            if (!SubchainsInitialized)
            {
                ResetSubchains();
            }

            Predicate <string> realCondition = condition;

            if (realCondition == null)
            {
                realCondition = _alwaysTrueCondition.WordCondition;
            }

            ChainKey currKey  = _currKey;
            string   currWord = CurrentWord;

            string[] newChainKeyVals = new string[currKey.Words.Length];
            for (int i = 0; i < currKey.Words.Length - 1; i++)
            {
                newChainKeyVals[i] = currKey.Words[i + 1];
            }
            newChainKeyVals[currKey.Words.Length - 1] = currWord;
            currKey = new ChainKey(newChainKeyVals);

            List <string> potentialWords = null;

            try
            {
                potentialWords = _chains.GetValues(currKey);
            }
            catch (Exceptions.InvalidKey)
            {
                //if we get here that means we hit the end of the list
                newChainKeyVals = GetRandomKey(_onEndSubChains, ck => !ck.Equals(currKey)).Words;
                currKey         = new ChainKey(newChainKeyVals);
                potentialWords  = _chains.GetValues(currKey);
            }

            bool candidateFound = GetCandidate(potentialWords, condition, out currWord);

            if (!candidateFound)
            {
                throw new Exceptions.NoPossibleElements("Unable to find a state matching given conditions");
            }

            _currKey    = currKey;
            CurrentWord = currWord;
            return(currWord);
        }
예제 #7
0
        /// <summary>
        /// Generate markov chains using input text
        /// </summary>
        public void GenerateChains()
        {
            //Split text
            string[]      splits         = _text.Split();
            List <string> advancedSplits = new List <string>();

            foreach (string baseSplit in splits)
            {
                advancedSplits.AddRange(StringUtils.SplitAndKeep(baseSplit.ToLower(), _delims));
            }


            Chains = new ChainMap();
            if (advancedSplits.Count < _chainSize * 2)
            {
                throw new Exceptions.InvalidArguments(string.Format("Chain size: {0} to small relative to text split {1}",
                                                                    _chainSize, advancedSplits.Count));
            }

            //Insert null elements in the beginning so chains are created for the first _chainSize elements
            for (int i = 0; i < _chainSize; i++)
            {
                advancedSplits.Insert(0, null);
            }

            List <string> .Enumerator listEnum = advancedSplits.GetEnumerator();

            string[] chainWords = new string[_chainSize];

            for (int i = 0; i < _chainSize; i++)
            {
                listEnum.MoveNext();
                chainWords[i] = listEnum.Current;
            }

            while (listEnum.MoveNext())
            {
                string   current = listEnum.Current;
                ChainKey currKey = new ChainKey(chainWords);
                Chains.AddToChain(currKey, current);

                for (int i = 0; i < _chainSize - 1; i++)
                {
                    chainWords[i] = chainWords[i + 1];
                }
                chainWords[_chainSize - 1] = current;
            }
        }
예제 #8
0
        /// <summary>
        /// Reset using currently existing initialCondition and onEndCondition
        /// This should be a low cpu usage operation
        /// </summary>
        public void ResetReadOnly()
        {
            //verify if reset has never been called
            if (!SubchainsInitialized)
            {
                throw new Exceptions.InitializationRequired("ResetReadOnly should be called after a regular reset");
            }

            //All chains and words should match condition so we can just get random
            ChainKey currKey = GetRandomKey(_initialConditionSubKeys);
            string   currWord;

            GetCandidate(_initialConditionSubChains.GetValues(currKey), null, out currWord);
            CurrentWord = currWord;
            _currKey    = currKey;
        }
예제 #9
0
        public override bool Equals(object obj)
        {
            ChainKey other = obj as ChainKey;

            if (other == null)
            {
                return(false);
            }
            if (other.Words.Length != Words.Length)
            {
                return(false);
            }

            //Ensure all words are equal
            for (int i = 0; i < Words.Length; i++)
            {
                if (Words[i] != other.Words[i])
                {
                    return(false);
                }
            }
            return(true);
        }
예제 #10
0
        /// <summary>
        /// Generate markov chains using input text
        /// </summary>
        public void GenerateChains()
        {
            //Split text
            string[] splits = _text.Split() ;
            List<string> advancedSplits = new List<string>() ;
            foreach(string baseSplit in splits)
            {
                advancedSplits.AddRange(StringUtils.SplitAndKeep(baseSplit.ToLower(), _delims)) ;
            }

            Chains = new ChainMap() ;
            if(advancedSplits.Count < _chainSize * 2)
            {
                throw new Exceptions.InvalidArguments(string.Format("Chain size: {0} to small relative to text split {1}",
                                                         _chainSize, advancedSplits.Count)) ;
            }

            //Insert null elements in the beginning so chains are created for the first _chainSize elements
            for(int i = 0 ; i < _chainSize ; i++)
            {
                advancedSplits.Insert(0, null) ;
            }

            List<string>.Enumerator listEnum = advancedSplits.GetEnumerator() ;

            string[] chainWords = new string[_chainSize] ;

            for(int i = 0 ; i < _chainSize ; i++)
            {
                listEnum.MoveNext();
                chainWords[i] = listEnum.Current ;
            }

            while(listEnum.MoveNext())
            {
                string current = listEnum.Current;
                ChainKey currKey = new ChainKey(chainWords) ;
                Chains.AddToChain(currKey, current) ;

                for(int i = 0 ; i < _chainSize - 1 ; i++)
                {
                    chainWords[i] = chainWords[i+1] ;
                }
                chainWords[_chainSize - 1] = current ;
            }
        }
예제 #11
0
        public void T_GetRandomKey_WithParams()
        {
            WordGenerator gen = InitSimpleWordGen() ;
            ChainMap subMap = new ChainMap() ;
            ChainKey key1 = new ChainKey(new string[]{"key1", "key2", "key3"}) ;
            ChainKey key2 = new ChainKey(new string[]{"key1", "key2", "key4"}) ;
            subMap.AddToChain(key1, "val1") ;
            subMap.AddToChain(key2, "val2") ;
            bool key1Found, key2Found ;
            key1Found = key2Found = false ;

            for(int i = 0 ; i < 10 ; i++)
            {
                ChainKey currKey = gen.GetRandomKey(subMap);
                if(key1.Equals(currKey))
                {
                    key1Found = true ;
                }
                else if(key2.Equals(currKey))
                {
                    key2Found = true ;
                }
                else
                {
                    Assert.Fail("Invalid key returned") ;
                }
            }
            if(!(key1Found && key2Found))
            {
                Assert.Fail("GetRandomKey is not random") ;
            }
        }
예제 #12
0
        /// <summary>
        /// Reset CurrentWord based on conditions
        /// </summary>
        /// <param name="keyCondition"> Condition for key of first word </param>
        /// <param name="onEndCondition"> Condition for new word after there are no more chains
        /// By default this is the same as @keyCondition   </param>
        private void Reset(ChainCondition initialCondition, ChainCondition onEndCondition)
        {
            ChainCondition realInitialConditions = initialCondition;

            //Set null conditions to always true conditions to simplify our code
            if (realInitialConditions == null)
            {
                realInitialConditions = _alwaysTrueCondition;
            }
            else
            {
                if (realInitialConditions.KeyCondition == null)
                {
                    realInitialConditions.KeyCondition = _alwaysTrueCondition.KeyCondition;
                }
                if (realInitialConditions.WordCondition == null)
                {
                    realInitialConditions.WordCondition = _alwaysTrueCondition.WordCondition;
                }
            }

            ChainCondition realOnEndCondition = onEndCondition;

            //Set on end condition to start condition if it is null
            if (realOnEndCondition == null)
            {
                realOnEndCondition = realInitialConditions;
            }
            else
            {
                if (realOnEndCondition.KeyCondition == null)
                {
                    realOnEndCondition.KeyCondition = _alwaysTrueCondition.KeyCondition;
                }
                if (realOnEndCondition.WordCondition == null)
                {
                    realOnEndCondition.WordCondition = _alwaysTrueCondition.WordCondition;
                }
            }

            ChainMap initialConditionMap;

            //Only generate subchains if we need to
            if (realInitialConditions != _alwaysTrueCondition)
            {
                initialConditionMap = GetSubChain(realInitialConditions);
            }
            else
            {
                initialConditionMap = Chains;
            }

            ChainKey[] initialConditionSubKeys = CreateKeysArray(initialConditionMap,
                                                                 _alwaysTrueCondition.KeyCondition);

            //All chains and words should match condition so we can just get random
            ChainKey currKey = GetRandomKey(initialConditionSubKeys);
            string   currWord;

            GetCandidate(initialConditionMap.GetValues(currKey), null, out currWord);

            if (realOnEndCondition != _alwaysTrueCondition)
            {
                //Verify on end map has valid elements.  If no exception is thrown we are good to go
                _onEndSubChains = GetSubChain(realOnEndCondition);
            }
            else
            {
                _onEndSubChains = initialConditionMap;
            }

            CurrentWord = currWord;
            _currKey    = currKey;
            _initialConditionSubChains = initialConditionMap;
            _initialConditionSubKeys   = initialConditionSubKeys;
            _currentOnEndCondition     = realOnEndCondition;
            SubchainsInitialized       = true;
        }
예제 #13
0
        /// <summary>
        /// Reset CurrentWord based on conditions
        /// </summary>
        /// <param name="keyCondition"> Condition for key of first word </param>
        /// <param name="onEndCondition"> Condition for new word after there are no more chains
        /// By default this is the same as @keyCondition   </param>
        private void Reset(ChainCondition initialCondition, ChainCondition onEndCondition)
        {
            ChainCondition realInitialConditions = initialCondition;
            //Set null conditions to always true conditions to simplify our code
            if(realInitialConditions == null)
            {
                realInitialConditions = _alwaysTrueCondition;
            }
            else
            {
                if (realInitialConditions.KeyCondition == null)
                {
                    realInitialConditions.KeyCondition = _alwaysTrueCondition.KeyCondition;
                }
                if (realInitialConditions.WordCondition == null)
                {
                    realInitialConditions.WordCondition = _alwaysTrueCondition.WordCondition;
                }
            }

            ChainCondition realOnEndCondition = onEndCondition ;
            //Set on end condition to start condition if it is null
            if(realOnEndCondition == null)
            {
                realOnEndCondition = realInitialConditions ;
            }
            else
            {
                if (realOnEndCondition.KeyCondition == null)
                {
                    realOnEndCondition.KeyCondition = _alwaysTrueCondition.KeyCondition;
                }
                if (realOnEndCondition.WordCondition == null)
                {
                    realOnEndCondition.WordCondition = _alwaysTrueCondition.WordCondition;
                }
            }

            ChainMap initialConditionMap ;
            //Only generate subchains if we need to
            if(realInitialConditions != _alwaysTrueCondition)
              	{
                initialConditionMap = GetSubChain(realInitialConditions) ;
            }
            else
            {
                initialConditionMap = Chains;
            }

            ChainKey[] initialConditionSubKeys = CreateKeysArray(initialConditionMap,
                                                                 _alwaysTrueCondition.KeyCondition) ;

            //All chains and words should match condition so we can just get random
            ChainKey currKey = GetRandomKey(initialConditionSubKeys) ;
            string currWord ;
            GetCandidate(initialConditionMap.GetValues(currKey), null, out currWord) ;

            if(realOnEndCondition != _alwaysTrueCondition)
            {
                //Verify on end map has valid elements.  If no exception is thrown we are good to go
                _onEndSubChains = GetSubChain(realOnEndCondition) ;
            }
            else
            {
                _onEndSubChains = initialConditionMap;
            }

            CurrentWord = currWord;
            _currKey = currKey;
            _initialConditionSubChains = initialConditionMap ;
            _initialConditionSubKeys = initialConditionSubKeys;
            _currentOnEndCondition = realOnEndCondition;
            SubchainsInitialized = true ;
        }
예제 #14
0
 /// <summary>
 /// Get a random key from passed in chain array
 /// </summary>
 /// <returns></returns>
 internal ChainKey GetRandomKey(ChainKey[] ckList)
 {
     return ckList[_rand.Next(ckList.Length)];
 }
예제 #15
0
        /// <summary>
        /// Reset using currently existing initialCondition and onEndCondition
        /// This should be a low cpu usage operation
        /// </summary>
        public void ResetReadOnly()
        {
            //verify if reset has never been called
            if(!SubchainsInitialized)
            {
                throw new Exceptions.InitializationRequired("ResetReadOnly should be called after a regular reset") ;
            }

            //All chains and words should match condition so we can just get random
            ChainKey currKey = GetRandomKey(_initialConditionSubKeys) ;
            string currWord ;
            GetCandidate(_initialConditionSubChains.GetValues(currKey), null, out currWord) ;
            CurrentWord = currWord;
            _currKey = currKey;
        }
예제 #16
0
        /// <summary>
        /// Get next word.  If the next natural word does not obey given predicate, throw exception
        /// If we reach the end of the list get random key matching end condition passed in Reset
        /// </summary>
        /// <param name="condition"> Predicate next word must obey </param>
        /// <returns></returns>
        public string GetNextWord(Predicate<string> condition)
        {
            //If word generator has never been reset, reset with default values
            if(!SubchainsInitialized)
            {
                ResetSubchains() ;
            }

            Predicate<string> realCondition = condition ;
            if(realCondition == null)
            {
                realCondition = _alwaysTrueCondition.WordCondition;
            }

            ChainKey currKey = _currKey;
            string currWord = CurrentWord;
            string[] newChainKeyVals = new string[currKey.Words.Length] ;
            for(int i = 0 ; i < currKey.Words.Length - 1 ; i++)
            {
                newChainKeyVals[i] = currKey.Words[i+1] ;
            }
            newChainKeyVals[currKey.Words.Length - 1] = currWord ;
            currKey = new ChainKey(newChainKeyVals) ;

            List<string> potentialWords = null ;
            try
            {
                potentialWords = _chains.GetValues(currKey) ;
            }
            catch(Exceptions.InvalidKey)
            {
                //if we get here that means we hit the end of the list
                newChainKeyVals = GetRandomKey(_onEndSubChains, ck => !ck.Equals(currKey)).Words;
                currKey = new ChainKey(newChainKeyVals) ;
                potentialWords = _chains.GetValues(currKey) ;
            }

            bool candidateFound = GetCandidate(potentialWords, condition, out currWord) ;
            if(!candidateFound)
            {
                throw new Exceptions.NoPossibleElements("Unable to find a state matching given conditions") ;
            }

            _currKey = currKey;
            CurrentWord = currWord;
            return currWord;
        }